// vim: et:ts=4:sw=4:sts=4:ft=javascript

'use strict';

/*@
Ox.LargeVideoTimeline <f:Ox.Element> LargeTimeline Object
    () ->              <f> LargeTimeline Object
    (options) ->       <f> LargeTimeline Object
    (options, self) -> <f> LargeTimeline Object
    options <o> Options object
    self    <o> shared private variable
@*/

Ox.LargeVideoTimeline = function(options, self) {

    self = self || {};
    var that = Ox.Element({}, self)
            .defaults({
                cuts: [],
                duration: 0,
                find: '',
                getImageURL: null,
                'in': 0,
                matches: [],
                out: 0,
                position: 0,
                style: 'default', // fixme: there are no different styles yet
                subtitles: [],
                type: 'player',
                width: 0
            })
            .options(options || {})
            .addClass('OxLargeVideoTimeline')
            .mouseleave(mouseleave)
            .mousemove(mousemove)
            .bindEvent({
                anyclick: click,
                dragstart: dragstart,
                drag: drag
            });

    Ox.extend(self, {
        $cuts: [],
        $pointMarker: {},
        $tiles: {},
        $tooltip: Ox.Tooltip({
            animate: false
        }),
        center: parseInt(self.options.width / 2),
        element: that.$element[0],
        fps: 25,
        height: 64,
        tileWidth: 1500
    });
    self.tiles = self.options.duration * self.fps / self.tileWidth;

    self.$timeline = $('<div>')
        .css({
            left: self.center + 'px'
        })
        .appendTo(that.$element)

    setSubtitles();

    self.options.cuts.forEach(function(v, i) {
        self.$cuts[i] = $('<img>')
            .addClass('OxCut')
            .attr({
                src: Ox.UI.getImageURL('markerCut')
            })
            .css({
                left: (v * self.fps) + 'px'
            })
            .appendTo(self.$timeline)
    });

    self.$markerPosition = $('<img>')
        .addClass('OxMarkerPosition')
        .attr({
            src: Ox.UI.getImageURL('markerPosition')
        })
        .appendTo(that.$element);
    setMarker();

    ['in', 'out'].forEach(function(point) {
        var titlecase = Ox.toTitleCase(point);
        self.$pointMarker[point] = $('<img>')
            .addClass('OxMarkerPoint' + titlecase)
            .attr({
                src: Ox.UI.getImageURL('marker' + titlecase)
            })
            .appendTo(self.$timeline);
        setPointMarker(point);
    });

    setWidth();
    setPosition();

    function click(data) {
        self.options.position = Ox.round(Ox.limit(
            getPosition(data), 0, self.options.duration
        ), 3);
        setPosition();
        triggerPositionEvent();
    }

    function dragstart(data) {
        self.drag = {x: data.clientX};
    }

    function drag(data) {
        self.options.position = Ox.round(Ox.limit(
            self.options.position + (self.drag.x - data.clientX) / self.fps,
            0, self.options.duration
        ), 3);
        self.drag.x = data.clientX;
        setPosition();
        triggerPositionEvent();
    }

    function getPosition(e) {
        return self.options.position + (e.clientX - that.offset().left - self.center - 1) / self.fps;
    }

    function mouseleave(e) {
        self.clientX = 0;
        self.clientY = 0;
        self.$tooltip.hide();
    }

    function mousemove(e) {
        self.clientX = e.clientX;
        self.clientY = e.clientY;
        updateTooltip();
    }

    function setMarker() {
        self.$markerPosition.css({
            left: self.center + 'px',
        });
    }

    function setPointMarker(point) {
        self.$pointMarker[point].css({
            left: (self.options[point] * self.fps) + 'px'
        });
    }

    function setPosition() {
        self.tile = parseInt(self.options.position * self.fps / self.tileWidth);
        self.$timeline.css({
            marginLeft: (-self.options.position * self.fps) + 'px'
        });
        Ox.loop(
            Math.max(self.tile - 1, 0),
            Math.min(self.tile + 2, self.tiles),
            function(i) {
                if (!self.$tiles[i]) {
                    self.$tiles[i] = $('<img>')
                        .attr({
                            src: self.options.getImageURL(i)
                        })
                        .css({
                            left: (i * self.tileWidth) + 'px'
                        })
                        .appendTo(self.$timeline);
                }
            }
        );
        if (self.clientX && self.clientY) {
            updateTooltip();
        }
    }

    function setSubtitles() {
        self.$subtitles = [];
        self.options.subtitles.forEach(function(subtitle, i) {
            var found = self.options.find &&
                subtitle.text.toLowerCase().indexOf(self.options.find.toLowerCase()) > -1;
            self.$subtitles[i] = $('<div>')
                .addClass('OxSubtitle' + (found ? ' OxHighlight' : ''))
                .css({
                    left: (subtitle['in'] * self.fps) + 'px',
                    width: (((subtitle.out - subtitle['in']) * self.fps) - 2) + 'px'
                })
                .html(Ox.highlight(subtitle.text, self.options.find, 'OxHighlight'))
                .appendTo(self.$timeline);
        });
    }

    function setWidth() {
        self.center = parseInt(self.options.width / 2);
        that.css({
            width: self.options.width + 'px'
        });
        self.$timeline.css({
            left: self.center + 'px'
        });
        setMarker();
    }

    function triggerPositionEvent() {
        that.triggerEvent('position', {
            position: self.options.position
        });
    }

    function updateTooltip() {
        var position = getPosition(self);
        if (position >= 0 && position <= self.options.duration) {
            self.$tooltip
                .options({
                    title: Ox.formatDuration(position, 3)
                })
                .show(self.clientX, self.clientY);
        } else {
            self.$tooltip.hide();
        }
    }

    self.setOption = function(key, value) {
        if (key == 'find') {
            that.find('.OxSubtitle').remove();
            setSubtitles();
        } else if (key == 'in' || key == 'out') {
            setPointMarker(key);
        } else if (key == 'position') {
            setPosition();
        } else if (key == 'subtitles') {
            
        } else if (key == 'width') {
            setWidth();
        }
    };

    return that;

};
