var Plasma = (function () {

    "use strict";

    var _model,
        _duration = 0,
        _sync,
        _width,
        _height,
        _ctx,
        _preflightCallback;

    var TRIANGLE_DIAMETER,
        TRIANGLE_DIAMETER_HALF,
        _feedWidth,
        _feedHeight,
        _triangleOffsetX,
        _triangleOffsetY,
        _bctx;

    var _tctx,
        _pyTree,
        _spriteArray,
        _lastSpriteIndex = 0;

    var _blackFade,
        _glow,
        _logoAlpha,
        _treeMax,
        _treeMin,
        _treeSpriteIndex,
        _treeScale,
        _treeOffset,
        _treeVal;

    function preflight(callbackFn, duration, model) {
        _preflightCallback = callbackFn;

        _duration = duration;
        _model = model;

        _sync = _model.sync;
        _width = _model.width();
        _height = _model.height();

        initSync();

        _ctx = _model.twoDeeRenderer;

        _preflightCallback();
    }

    function init() {
        _model.on("resize", resize);


        var _boxPadding = Math.round(37 / 1920 * _width);

        var _vctx = _model.vignette;
        _vctx.clearRect(0, 0, _width, _height);
        _vctx.strokeStyle = "#ffffff";
        _vctx.fillStyle = "#ffffff";

        _vctx.lineWidth = Math.round(2 / 1920 * _width);
        _vctx.strokeRect(_boxPadding, _boxPadding, _width - (2 * _boxPadding), _height - (2 * _boxPadding));


        if (_ctx.setLineDash)
            _ctx.setLineDash([0]);
        else{
            try {
                _ctx.mozDash = [1];
            } catch(error) {}
        }

        TRIANGLE_DIAMETER = 50 / 1920 * _width;
        TRIANGLE_DIAMETER_HALF = TRIANGLE_DIAMETER / 2;

        var c = document.createElement('canvas');
        _feedWidth = Math.ceil((_width / TRIANGLE_DIAMETER) + 1);
        _feedHeight = (Math.ceil((_height / TRIANGLE_DIAMETER) + 1) * 2);
        c.width = _feedWidth;
        c.height = _feedHeight;

        _triangleOffsetX = ((_feedWidth * TRIANGLE_DIAMETER) - _width) / 2;
        _triangleOffsetY = ((_feedHeight * TRIANGLE_DIAMETER_HALF) - _height) / 2;

        _bctx = c.getContext('2d');

        _bctx.strokeWidth = 2;

    //--
        _spriteArray = [Meat.g0, Meat.g1, Meat.g2, Meat.g3, Meat.g4, Meat.g5, Meat.g6, Meat.g7, Meat.g8, Meat.g9,Meat.g10,
            Meat.g11, Meat.g12, Meat.g13, Meat.g14, Meat.g15, Meat.g16, Meat.g17, Meat.g18, Meat.g19, Meat.g20,
            Meat.g21, Meat.g22, Meat.g23, Meat.g24];

        c = document.createElement('canvas');
        c.width = _width,
        c.height = _height;

        _tctx = c.getContext('2d');

        _pyTree = new PyTree();
        _pyTree.setContext(_tctx);

        _pyTree.setImage(_spriteArray[_lastSpriteIndex]);

        _bctx.fillStyle = '#312d34';
        _bctx.fillRect(0, 0, _feedWidth, _feedHeight);
    }

    function initSync() {

        _blackFade = _sync.getTrack('blackFade');
        _glow = _sync.getTrack('glow');
        _logoAlpha = _sync.getTrack('logoAlpha');
        _treeMax = _sync.getTrack('treeMaxDepth');
        _treeMin = _sync.getTrack('treeMinDepth');
        _treeSpriteIndex =  _sync.getTrack('treeSpriteIndex');
        _treeScale = _sync.getTrack('treeScale');
        _treeVal = _sync.getTrack('treeVal');
    }

    function render(sceneTime, floatBeat, frameDelta, row) {

        _ctx.fillStyle = 'rgba(255,255,255,.04)';
        _ctx.fillRect(0, 0, _ctx.canvas.width, _ctx.canvas.height);

        var t = row * 100;
        var radgrad = _bctx.createRadialGradient(Math.sin(t / 1200) * 20 + 20, Math.cos(t / 800) * 28 + 5, 10,
            Math.sin(t / 1200) * 20 + 30, Math.cos(t / 800) * 28 + 10, 31);
        radgrad.addColorStop(0, '#312d34');
        radgrad.addColorStop(0.9, '#f6ab72');
        radgrad.addColorStop(1, 'rgba(1,159,98,0)');

        _bctx.save();
        _bctx.globalAlpha = .5;
        //_bctx.globalCompositeOperation = 'lighter';
        _bctx.fillStyle = radgrad;
        _bctx.fillRect(0, 0, _feedWidth, _feedHeight);
        _bctx.restore();
        /*
        _bctx.save();
        _bctx.globalCompositeOperation = 'lighter';

        /*
        for(var c = 0; c < _feedHeight; c++){
            _bctx.beginPath();
            var alpha = .4;//(.02 / 2 * (Math.sin(row / 10) + 1)) + .02;

            if(c % 2 == 0){
                _bctx.strokeStyle = 'rgba(255,255,255,' + alpha + ')';
                _bctx.moveTo(0, c);
                _bctx.lineTo(_feedWidth, c * 2);
            } else {
                _bctx.strokeStyle = 'rgba(0,0,0,' + alpha + ')';
                _bctx.moveTo(0, c * 2);
                _bctx.lineTo(_feedWidth, c);
            }

            _bctx.stroke();
            _bctx.closePath();
            //_bctx.fillRect(0, c, _feedWidth, c + 2);
        }
        _bctx.restore();
*/
        //fill pic
        var d = _bctx.getImageData(0, 0, _feedWidth, _feedHeight).data;

        for (var i = 0, len = d.length; i < len; i += 4) {

            var col = 'rgba(' + d[i] + ',' + d[i + 1] + ',' + d[i + 2] + ',' + d[i + 3] + ')',
                y = Math.floor(i / (4 * _feedWidth)),
                x = (i - (y * 4 * _feedWidth)) / 4;

            triangle(x, y, col);
        }

        var newIndex = Math.floor(_treeSpriteIndex.getValue(row));

        if(_lastSpriteIndex != newIndex) {
            _pyTree.setImage(_spriteArray[newIndex]);
            _lastSpriteIndex = newIndex;
        }

        //pyTree
        _pyTree.setMaxDepth(_treeMax.getValue(row));
        _pyTree.setMinDepth(_treeMin.getValue(row));


        _pyTree.render(_treeVal.getValue(row));
        var pyScale = _treeScale.getValue(row),//Math.abs(Math.sin(row)),
            pyOffsetY = 0;//(_height * pyScale) / 100 * (100 * pyScale);

        _tctx.globalAlpha = _logoAlpha.getValue(row);
        _ctx.drawImage(_tctx.canvas, (_width - (_width * pyScale)) * 0.5, ((_height - (_height * pyScale)) * 0.5) + pyOffsetY, _width * pyScale, _height * pyScale);

        var glow = _glow.getValue(row);
        if (glow > 0) {
            var glowScale = 1;

            for (i = 0; i < 4; i++) {
                glowScale += .01;
                var sW = _width * glowScale,
                    sH = _height * glowScale;
                _ctx.save();
                _ctx.globalCompositeOperation = 'lighter';
                _ctx.globalAlpha = glow;
                _ctx.drawImage(_ctx.canvas, (_width - sW) / 2, (_height - sH) / 2, sW, sH);
                _ctx.restore();
            }
        }

        var bF = _blackFade.getValue(row);
        if (bF > 0) {
            _ctx.fillStyle = "rgba(0,0,0," + bF + ")";
            _ctx.fillRect(0, 0, _width, _height);
        }
    }

    function triangle(posX, posY, color) {
        var x = (posX * TRIANGLE_DIAMETER) + _triangleOffsetY,
            y = (posY * TRIANGLE_DIAMETER_HALF) - _triangleOffsetY;

        _ctx.fillStyle = color;
        _ctx.beginPath();

        posX += (posY % 2);

        if (posX % 2 == 0) {
            _ctx.moveTo(x, y - TRIANGLE_DIAMETER_HALF);
            _ctx.lineTo(x - TRIANGLE_DIAMETER, y);
            _ctx.lineTo(x, y + TRIANGLE_DIAMETER_HALF);
            _ctx.lineTo(x, y - TRIANGLE_DIAMETER_HALF);
        } else {
            _ctx.moveTo(x - TRIANGLE_DIAMETER, y - TRIANGLE_DIAMETER_HALF);
            _ctx.lineTo(x, y);
            _ctx.lineTo(x - TRIANGLE_DIAMETER, y + TRIANGLE_DIAMETER_HALF);
            _ctx.lineTo(x - TRIANGLE_DIAMETER, y - TRIANGLE_DIAMETER_HALF);
        }
        _ctx.closePath();
        _ctx.fill();
    }

    function onBeat(integerBeat, msTime, majorBeat, minorBeat) {
    }

    function clear() {
        _model.on("resize", function () {
        });
    }

    function resize(width, height) {
        _width = width;
        _height = height;
    }

    return {
        preflight: preflight,
        init: init,
        render: render,
        onBeat: onBeat,
        clear: clear,
        resize: resize
    };
}());