Ox.SmallVideoTimeline = function(options, self) {

    self = self || {};
    var that = Ox.Element({}, self)
        .defaults({
            _offset: 0, // hack for cases where all these position: absolute elements have to go into a float: left
            duration: 0,
            editing: false,
            find: '',
            'in': 0,
            out: 0,
            paused: false,
            showMilliseconds: 0,
            timeline: '',
            type: 'player',
            width: 256
        })
        .options(options || {})
        .addClass('OxSmallVideoTimeline')
        .css(Ox.extend({
            width: self.options.width + 'px'
        }, self.options.type == 'player' ? {
            background: 'rgb(0, 0, 0)',
            borderRadius: '8px'
        } : {}));

    self.height = self.options.type == 'player' ? 16 : 24;
    self.imageLeft = self.options.type == 'player' ? 8 : 4;
    self.imageWidth = self.options.width -
        (self.options.type == 'player' ? 16 : 8)
    self.imageHeight = self.options.type == 'player' ? 16 : 18;
    self.interfaceLeft = self.options.type == 'player' ? 0 : 4;
    self.interfaceTop = self.options.type == 'player' ? 0 : 2;
    self.interfaceWidth = self.options.type == 'player' ? self.options.width : self.imageWidth;

    that.css({
        height: self.height + 'px'
    });

    self.$image = getTimelineImage().appendTo(that);

    self.$interface = Ox.Element({
            tooltip: getTooltip
        })
        .addClass('OxInterface')
        .css({
            left: self.interfaceLeft + 'px',
            top: self.interfaceTop + 'px',
            width: self.interfaceWidth + 'px',
            height: '20px',
        })
        .bind({
            mousedown: mousedown
        })
        .bindEvent({
            drag: function(data) {
                mousedown(data);
            },
            dragend: function(data) {
                self.triggered = false;
                mousedown(data);
            }
        })
        .appendTo(that);

    self.$interface.$tooltip.css({
        textAlign: 'center'
    });

    if (self.options.type == 'player') {
        self.$positionMarker = $('<div>')
            .addClass('OxMarkerPlay' + (self.options.paused ? ' OxPaused' : ''))
            .append($('<div>').append($('<div>')))
            .appendTo(that.$element);
    } else {
        self.$positionMarker = $('<img>')
            .addClass('OxMarkerPosition')
            .attr({
                src: Ox.UI.getImageURL('markerPosition')
            })
            .appendTo(that.$element);
    }
    setPositionMarker();

    if (self.options.type == 'editor') {
        self.$pointMarker = {};
        ['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(that.$element);
            setPointMarker(point);
        });
    }

    function getPosition(e) {
        var position = (
                (e.offsetX ? e.offsetX : e.clientX - $(e.target).offset().left) -
                (self.options.type == 'player' ? 8 : 0)
            ) * self.options.duration / self.imageWidth;
        return Ox.limit(position, 0, self.options.duration);
    }

    function getSubtitle(position) {
        var subtitle = '';
        Ox.forEach(self.options.subtitles, function(v) {
            if (v['in'] <= position && v.out > position) {
                subtitle = v;
                return false;
            }
        });
        return subtitle;
    }

    function getTimelineImage() {
        return Ox.SmallVideoTimelineImage({
            duration: self.options.duration,
            editing: self.options.editing,
            'in': self.options['in'],
            out: self.options.out,
            results: self.options.results,
            subtitles: self.options.subtitles,
            timeline: self.options.timeline,
            width: self.imageWidth,
            type: self.options.type
        })
        .css({
            position: 'absolute',
            left: self.imageLeft + 'px',
            width: self.imageWidth + 'px'
        });
    }

    function getTooltip(e) {
        var position = getPosition(e),
            subtitle = getSubtitle(position);
        return subtitle ? '<span class=\'OxBright\'>' + Ox.highlight(
                subtitle.text, self.options.find, 'OxHighlight'
            ).replace(/\n/g, '<br/>') + '</span><br/>' +
            Ox.formatDuration(subtitle['in'], self.options.showMilliseconds) + ' - ' +
            Ox.formatDuration(subtitle['out'], self.options.showMilliseconds) :
            Ox.formatDuration(position, self.options.showMilliseconds);
    }

    function mousedown(e) {
        if ($(e.target).is('.OxInterface')) {
            self.options.position = getPosition(e);
            setPositionMarker();
            if (!self.triggered) {
                that.triggerEvent('position', {
                    position: self.options.position
                });
                self.triggered = true;
                setTimeout(function() {
                    self.triggered = false;
                }, 250);
            }
        }
    }

    function setPointMarker(point) {
        self.$pointMarker[point].css({
            left: self.imageLeft + Math.round(
                self.options[point] * self.imageWidth / self.options.duration
            ) + 'px'
        });
    }

    function setPositionMarker() {
        self.$positionMarker.css({
            left: self.interfaceLeft + Math.round(
                self.options.position * self.imageWidth / self.options.duration
            ) - (self.options.type == 'editor' ? 5 : 0) + self.options._offset + 'px'
        });
    }

    function setWidth() {
        self.imageWidth = self.options.width -
            (self.options.type == 'player' ? 16 : 8);
        self.interfaceWidth = self.options.type == 'player' ?
            self.options.width : self.imageWidth;
        that.css({
            width: self.options.width + 'px'
        });
        self.$image.options({
            width: self.imageWidth
        }).css({
            width: self.imageWidth + 'px'
        });
        self.$interface.css({
            width: self.interfaceWidth + 'px'
        });
        setPositionMarker();
        if (self.options.type == 'editor') {
            setPointMarker('in');
            setPointMarker('out');
        }
    }

    self.setOption = function(key, value) {
        if (key == 'duration') {
            self.$image.options({
                duration: value
            });
        } else if (key == 'in') {
            self.$image.options({
                'in': value
            });
            setPointMarker('in');
        } else if (key == 'out') {
            self.$image.options({
                out: value
            });
            setPointMarker('out');
        } else if (key == 'paused') {
            self.$positionMarker[
                self.options.paused ? 'addClass' : 'removeClass'
            ]('OxPaused');
        } else if (key == 'position') {
            setPositionMarker();
        } else if (key == 'results') {
            self.$image.options({
                results: value
            });
        } else if (key == 'subtitles') {
            self.$image.options({
                subtitles: value
            });
        } else if (key == 'width') {
            setWidth();
        }
    };

    return that;

};