var WakeyWakey = (function () {

    "use strict";

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

    var _fxPixel,
        _pCloud,
        _bgGradient,
        _blackFade,
        _glow;

    var _dash,
        _boxPadding;

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

        _boxPadding = Math.round(37 / 1920 * _width);
        _vctx = _model.vignette;
        _vctx.clearRect(0, 0, _width, _height);
        _vctx.drawImage(Meat.vignette, 0, 0, _width, _height);

        _ctx.lineCap = 'square';
        _dash = [Math.ceil(20 / 1920 * _width), Math.ceil(7 / 1920 * _width)];//[13, 11, 7, 5, 3, 2];

        _fxPixel = new Pixel();
        _fxPixel.setContext(_ctx);
        _pCloud = [];

        _bgGradient = _ctx.createLinearGradient(0, 0, _width, _height);
        _bgGradient.addColorStop(0, "#ccd3d3");
        _bgGradient.addColorStop(1, "#87898f");

        for (var i = 0; i < 120; i++) {
            _pCloud[i] = [];
            var offsetX = Random.float() * _width - _width / 7 + _width / 10,
                offsetY = _height - (Random.float() * _height),
                rnd = Random.float();

            for (var c = 0; c < 3; c++) {
                var originalX = Random.float() * _width / 10 + offsetX,
                    originalY = Random.float() * _height / 10 + offsetY;

                _pCloud[i].push({'oX': originalX, 'oY': originalY,
                    'x': originalX, 'y': originalY, 'rnd': rnd});
            }
        }
    }

    function initSync() {
        _blackFade = _sync.getTrack('blackFade');
        _glow = _sync.getTrack('glow');
    }

    var _lastRow;

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

        //flickr
        if (_lastRow != Math.floor(row)) {

            _lastRow = Math.floor(row);

            if (_lastRow % 16 == 0)
                rotateTriangles(.001);
        }

        _ctx.fillStyle = _bgGradient;
        _ctx.fillRect(0, 0, _width, _height);

        _ctx.strokeStyle = "#f2fafa";
        _ctx.lineWidth = 5 / 1920 * _width;

        if (_ctx.setLineDash)
            _ctx.setLineDash(_dash);
        else {
            try {
                _ctx.mozDash = _dash;
            } catch (error) {
            }
        }

        drawTriangles(row);

        var glow = _glow.getValue(row);

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

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

        _ctx.strokeStyle = "#ffffff";
        _ctx.lineWidth = 2 / 1920 * _width;

        _ctx.strokeRect(_boxPadding,  _boxPadding, Math.round(_width - (2 *  _boxPadding)), Math.round(_height - (2 *  _boxPadding)));

        var bF = _blackFade.getValue(row);

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

    function drawTriangles(inputRow) {
        //draw multiple times to get crisp line

        for (var c = 0; c < 1; c++) {
            var row = inputRow;
            for (var i = 0, len = _pCloud.length; i < len; i++) {
                _pCloud[i][0].y = row + _height * (_pCloud[i][0].rnd * 2) - _pCloud[i][0].oY;
                _ctx.beginPath();
                _ctx.moveTo(_pCloud[i][0].x, _pCloud[i][0].y);

                _pCloud[i][1].y = (row + _height) * (_pCloud[i][1].rnd * 2) - _pCloud[i][1].oY;
                _ctx.lineTo(_pCloud[i][1].x, _pCloud[i][1].y);

                _pCloud[i][2].y = (row + _height) * (_pCloud[i][2].rnd * 2) - _pCloud[i][2].oY;
                _ctx.lineTo(_pCloud[i][2].x, _pCloud[i][2].y);

                //and back to start
                _ctx.lineTo(_pCloud[i][0].x, _pCloud[i][0].y);
                _ctx.stroke();
                _ctx.closePath();
            }
        }
    }

    function rotateTriangles(angle) {

        for (var i = 0, len = _pCloud.length; i < len; i += 3) {
            for (var c = 0; c < 3; c++) {
                _pCloud[i][c].x = (_pCloud[i][c].oX * Math.cos(angle) - _pCloud[i][c].y * Math.sin(angle));
                _pCloud[i][c].oY = (_pCloud[i][c].oX * Math.sin(angle) + _pCloud[i][c].y * Math.cos(angle));
            }
        }
    }

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