Ox.SmallVideoTimelineImage = function(options, self) {

    self = self || {};
    var that = Ox.Element({}, self)
        .defaults({
            duration: 0,
            editing: false,
            'in': 0,
            out: 0,
            results: [],
            subtitles: [],
            timeline: '',
            width: 256,
            type: 'player'
        })
        .options(options || {})
        .css({
            position: 'absolute',
            width: self.options.width + 'px'
        });

    self.images = Ox.isString(self.options.timeline) ?
        1 : Math.ceil(self.options.duration / 3600);
    self.imageWidth = Ox.isString(self.options.timeline) ?
        1920 : Math.round(self.options.duration);
    self.height = self.options.type == 'player' ? 16 : 24;
    self.imageHeight = self.options.type == 'player' ? 16 : 18;
    self.imageTop = self.options.type == 'player' ? 0 : 3;
    self.timelineTop = self.options.type == 'player' ? 0 : 4;

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

    if (Ox.isString(self.options.timeline)) {
        self.$timeline = $('<img>')
            .attr({
                src: self.options.timeline
            })
            .css({
                position: 'absolute',
                top: self.timelineTop + 'px',
                width: self.options.width + 'px',
                height: '16px'
            })
            .appendTo(that.$element);
    } else {
        Ox.loop(self.images, function(i) {
            $('<img>')
                .attr({
                    src: self.options.timeline(i)
                })
                .css({
                    position: 'absolute',
                    left: (i * 3600) + 'px',
                    top: self.timelineTop + 'px',
                    width: (i == self.images - 1 ? self.imageWidth % 3600 : 3600) + 'px',
                    height: '16px'
                })
                .appendTo(that.$element);
        });
    }

    self.$subtitles = $('<img>')
        .attr({
            src: getImageURL('subtitles')
        })
        .css({
            position: 'absolute',
            top: self.imageTop + 'px',
            width: self.options.width + 'px',
            height: self.imageHeight + 'px'
        })
        .appendTo(that.$element);

    self.$results = $('<img>')
        .attr({
            src: getImageURL('results')
        })
        .css({
            position: 'absolute',
            top: self.imageTop + 'px',
            width: self.options.width + 'px',
            height: self.imageHeight + 'px'
        })
        .appendTo(that.$element);

    self.$selection = $('<img>')
        .attr({
            src: getImageURL('selection')
        })
        .css({
            position: 'absolute',
            top: self.imageTop + 'px',
            width: self.options.width + 'px',
            height: self.imageHeight + 'px'
        })
        .appendTo(that.$element);

    function getImageURL(image, callback) {
        var width = image == 'results' || image == 'selection' ?
                self.options.width : self.imageWidth,
            height = self.imageHeight,
            canvas = $('<canvas>')
                .attr({
                    width: width,
                    height: height
                })[0],
            context = canvas.getContext('2d'),
            imageData = context.createImageData(width, height),
            data = imageData.data;
        if (image == 'results') {
            var top = 0,
                bottom = height;
            self.options.results.forEach(function(result) {
                var left = Math.round(
                        result['in'] / self.options.duration * width
                    ),
                    right = Math.round(
                        result.out / self.options.duration * width
                    ) + 1;
                Ox.loop(left, right, function(x) {
                    Ox.loop(top, bottom, function(y) {
                        var color = self.options.type == 'player' ?
                                [255, 255, 0, 128] :
                                (y == top || y == bottom - 1) ?
                                [255, 255, 0, 255] : [255, 255, 0, 64],
                            index = x * 4 + y * 4 * width;
                        data[index] = color[0];
                        data[index + 1] = color[1];
                        data[index + 2] = color[2];
                        data[index + 3] = color[3];
                    });
                });
            });
        } else if (image == 'selection' && self.options.out > self.options['in']) {
            var left = Math.round(
                    self.options['in'] / self.options.duration * width
                ),
                right = Math.round(
                    self.options.out / self.options.duration * width
                ) + 1,
                top = 0,
                bottom = height,
                rgb = self.options.editing ? [128, 255, 255] : [255, 255, 255];
            Ox.loop(left, right, function(x) {
                Ox.loop(top, bottom, function(y) {
                    var color = self.options.type == 'player' ?
                            [rgb[0], rgb[1], rgb[2], 128] :
                            [rgb[0], rgb[1], rgb[2], (y == top || y == bottom - 1) ? 255 : 64],
                        index = x * 4 + y * 4 * width;
                    data[index] = color[0];
                    data[index + 1] = color[1];
                    data[index + 2] = color[2];
                    data[index + 3] = color[3];
                });
            });
        } else if (image == 'subtitles') {
            var bottom = self.options.type == 'player' ? 14 : 15;
            self.options.subtitles.forEach(function(subtitle) {
                var left = Math.round(
                        subtitle['in'] / self.options.duration * self.imageWidth
                    ),
                    right = Math.round(
                        subtitle.out / self.options.duration * self.imageWidth
                    ) + 1,
                    top = bottom - subtitle.text.split('\n').length - 3;
                Ox.loop(left, right, function(x) {
                    Ox.loop(top, bottom, function(y) {
                        var color = y == top ? [0, 0, 0, 0] :
                            (y == top + 1 || y == bottom - 1) ?
                            [0, 0, 0, 128] : [255, 255, 255, 128],
                            index = x * 4 + y * 4 * width;
                        data[index] = color[0];
                        data[index + 1] = color[1];
                        data[index + 2] = color[2];
                        data[index + 3] = color[3];
                    });
                });
            });
        }
        context.putImageData(imageData, 0, 0);
        return canvas.toDataURL();
    }

    function getPosition() {
        
    }

    self.setOption = function(key, value) {
        if (key == 'in' || key == 'out') {
            self.$selection.attr({
                src: getImageURL('selection')
            });
        } else if (key == 'results') {
            self.$results.attr({
                src: getImageURL('results')
            });
        } else if (key == 'selection') {
            self.$selection.attr({
                src: getImageURL('selection')
            });
        } else if (key == 'subtitles') {
            self.$subtitles.attr({
                src: getImageURL('subtitles')
            });
        } else if (key == 'width') {
            that.css({width: value + 'px'});
            self.$results
                .attr({src: getImageURL('results')})
                .css({width: value + 'px'});
            self.$selection
                .attr({src: getImageURL('selection')})
                .css({width: value + 'px'});
            self.$subtitles.css({width: value + 'px'});
            self.$timeline.css({width: value + 'px'});
        }
    }

    return that;

}