var Polyfield = (function () {

    "use strict";

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

    var _starfield,
        _slice;

    var _blackFade,
        _logoAlpha,
        _logoStab,
        _logoAngle,
        _logoStripes,
        _logoMaxAmp,
        _glow;

    var _logoW,
        _logoH;

    var _tunnel,
        _tunnelFeed;

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

        _duration = duration;
        _model = model;

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

        initSync();

        _ctx = _model.twoDeeRenderer;

        var canvas = document.createElement('canvas');
        canvas.width = _width;
        canvas.height = _height;
        _logoCtx = canvas.getContext('2d');

        _slice = new Slice();
        _slice.setContext(_logoCtx);

        _logoW = Meat.trbl.width / 1920 * _width;
        _logoH = Meat.trbl.height / 1080 * _height;

        _preflightCallback();
    }

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

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

        _starfield = new Starfield();
        _starfield.setContext(_ctx);
        _starfield.setCenter(_width / 2, _height - (_height/3));
        _starfield.setSpeed(50);

        var canvas = document.createElement('canvas');
        canvas.width = _width;
        canvas.height = _height;
        _tunnelFeed = canvas.getContext('2d');

        _tunnel = new ZLayerTunnel();
        _tunnel.setContext(_ctx);
        _tunnel.setFeed(_tunnelFeed);
    }

    function initSync() {
        _blackFade = _sync.getTrack('blackFade');
        _glow = _sync.getTrack('glow');
        _logoAlpha = _sync.getTrack('logoAlpha');
        _logoStab = _sync.getTrack('logoStab');
        _logoAngle = _sync.getTrack('logoAngle');
        _logoStripes = _sync.getTrack('logoStripes');
        _logoMaxAmp = _sync.getTrack('logoMaxAmp');
    }

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

        var logoAlpha = _logoAlpha.getValue(row);

        if(logoAlpha > 0){
            _logoCtx.clearRect(0, 0, _width, _height);
            _logoCtx.save();
            _logoCtx.globalAlpha = logoAlpha;
            _logoCtx.drawImage(Meat.trbl, (_width - _logoW) / 2, (_height - _logoH) / 2, _logoW, _logoH);
            _logoCtx.restore();

            _slice.setAngle(_logoAngle.getValue(row));
            _slice.setStripes(_logoStripes.getValue(row));
            _slice.setMaxAmplitude(_logoMaxAmp.getValue(row));
            _slice.setAmplitudeMultiplicator(_logoStab.getValue(row));

            _slice.render(row);
        }

        _ctx.fillStyle = "#ff8673";
        _ctx.fillRect(0, 0, _width, _height);

        _tunnel.render(frameDelta/1000, row);

        _ctx.save();
        _starfield.render(frameDelta / 1000);
        _ctx.restore();

        if(logoAlpha > 0){
            _ctx.drawImage(_logoCtx.canvas, 0, 0);
        }

        var glow = _glow.getValue(row);

        var bF = _blackFade.getValue(row);

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

        if (glow > 0) {
            var glowScale = 1;

            for(var 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();
            }
        }
    }

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