'use strict';

/*@
Ox.SmallVideoTimelineImage <f> Small Video Timeline Image
    (options[, self]) -> <o:Ox.Element> Small Video Timeline Image
    options <o> Options
    self <o> Shared private variable
@*/
Ox.SmallVideoTimelineImage = function(options, self) {

    self = self || {};
    var that = Ox.Element({}, self)
        .defaults({
            duration: 0,
            imageURL: '',
            'in': 0,
            mode: 'player',
            out: 0,
            results: [],
            state: 'default',
            subtitles: [],
            type: '',
            width: 256
        })
        .options(options || {})
        .update({
            'in': function() {
                self.$selection.attr({
                    src: getImageURL('selection')
                });
            },
            out: function() {
                self.$selection.attr({
                    src: getImageURL('selection')
                });
            },
            results: function() {
                self.$results.attr({
                    src: getImageURL('results')
                });
            },
            selection: function() {
                self.$selection.attr({
                    src: getImageURL('selection')
                });
            },
            subtitles: function() {
                self.$subtitles.attr({
                    src: getImageURL('subtitles')
                });
            },
            state: function() {
                self.$selection.attr({
                    src: getImageURL('selection')
                });
            },
            width: function() {
                var width = self.options.width;
                that.css({width: width + 'px'});
                self.$results
                    .attr({src: getImageURL('results')})
                    .css({width: width + 'px'});
                self.$selection
                    .attr({src: getImageURL('selection')})
                    .css({width: width + 'px'});
                self.$subtitles.css({width: width + 'px'});
                self.$timeline.css({width: width + 'px'});
            }
        })
        .css({
            position: 'absolute',
            width: self.options.width + 'px'
        });

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

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

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

    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);

    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);

    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);

    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 alpha = self.options.mode == 'editor'
                                && (y == top || y == bottom - 1) ? 255 : 128,
                            color = [2, 3, 6].indexOf(x % 4 + y % 4) > -1
                                ? [0, 0, 0] : [255, 255, 0],
                            index = x * 4 + y * 4 * width;
                        data[index] = color[0];
                        data[index + 1] = color[1];
                        data[index + 2] = color[2];
                        data[index + 3] = alpha;
                    });
                });
            });
        } 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.state == 'editing' ? [[0, 128, 0], [128, 255, 128]]
                    : self.options.state == 'editable' ? [[0, 0, 128], [128, 128, 255]]
                    : self.options.state == 'selected' ? [[0, 0, 0], [255, 255, 255]]
                    : [[32, 32, 32], [224, 224, 224]];
            Ox.loop(left, right, function(x) {
                Ox.loop(top, bottom, function(y) {
                    var alpha = self.options.mode == 'editor'
                            && (y == top || y == bottom - 1) ? 255 : 128,
                        color = rgb[[2, 3, 6].indexOf(x % 4 + y % 4) > -1 ? 0 : 1],
                        index = x * 4 + y * 4 * width;
                    data[index] = color[0];
                    data[index + 1] = color[1];
                    data[index + 2] = color[2];
                    data[index + 3] = alpha;
                });
            });
        } else if (image == 'subtitles') {
            var bottom = self.options.mode == '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 - 2;
                Ox.loop(left, right, function(x) {
                    Ox.loop(top, bottom, function(y) {
                        var alpha = 128,
                            color = (y == top || y == bottom - 1) ? [0, 0, 0] : [255, 255, 255],
                            index = x * 4 + y * 4 * width;
                        data[index] = color[0];
                        data[index + 1] = color[1];
                        data[index + 2] = color[2];
                        data[index + 3] = alpha;
                    });
                });
            });
        }
        context.putImageData(imageData, 0, 0);
        return canvas.toDataURL();
    }

    return that;

};
