// mog
/*jslint devel: true, browser: true */
var Demo = (function () {
    "use strict";

    var _audio,
        _sceneList,
        _model,
        BPM = 125,
        BEAT_OFFSET = 0,
        AUDIO_URL = 'data/Chippy_Nr.425.ogg',
        AUDIO_VOLUME = 0.1,
        ROWS_PER_BEAT = 8,
        ROW_RATE = BPM / 60 * ROWS_PER_BEAT,
        _demoMode = true,
        _row = 0,
        LOOP_POSITION = 0,
        _syncDevice = new JSRocket.SyncDevice();

    var _readyToRoll = false;

    function start() {
        if (_demoMode) {
            _syncDevice.setConfig({'rocketXML':'data/dsm.rocket'});
            _syncDevice.init("demo");
        } else {
            _syncDevice.init();
        }

        _syncDevice.on('ready', syncReady);
        _syncDevice.on('update', onSyncUpdate);
        _syncDevice.on('play', onPlay);
        _syncDevice.on('pause', onPause);
    }

    function syncReady() {

        initAudio();
        initScenes();
    }

    function initAudio() {

        _audio = new Tune();
        _audio.loopPoint(LOOP_POSITION);
        _audio.on('play', onAudioReady);
        _audio.on("ended", onEnded);
        _audio.create(AUDIO_URL);
        //_audio.play();
    }

    function initScenes() {

        setModel();

        _sceneList = new SceneList(_model);
        _sceneList.setBPM(BPM);
        _sceneList.setBeatOffsetMs(BEAT_OFFSET);
        _sceneList.add(Tunnel, 0, 61920);

        _sceneList.on("ready", onPreflightDone);
        _sceneList.preflight();
    }

    function setModel() {

        _model = new Model();
        _model.stage = document.createElement('div');
        _model.stage.setAttribute('class', 'demo');
        document.getElementById('root').appendChild(_model.stage);
        _model.scale(false);
        _model.width(1920 / 1080 * window.innerHeight);
        _model.height(window.innerHeight);

        _model.stage.style.cssText = 'margin-left:' + (window.innerWidth - _model.width())/2 + 'px;';

        _model.BPM = BPM;
        _model.volume = AUDIO_VOLUME;
        _model.sync = _syncDevice;

        var canvas = document.createElement('canvas');
        canvas.style.cssText = 'position:absolute;top:0;left:' + (window.innerWidth - _model.width()) / 2 + 'px;';
        canvas.width = _model.width();
        canvas.height = _model.height();
        _model.twoDeeRenderer = canvas.getContext('2d');
        _model.stage.appendChild(canvas);
    }

    function onAudioReady() {

        //console.log("Rows", _audio.duration() * ROW_RATE);

        if (_readyToRoll === false) {
            return;
        }

        //nuke callback
        _audio.on("play", function () {
        });

        loop();
    }

    function onEnded() {
        document.getElementById('root').style.backgroundColor = "#fff";
        _model.stage.style.display = "none";
        document.getElementById("credits").style.display = "block";
    }

    function onSyncUpdate(row) {
        //on interpolation change, we don't get a valid row
        if (!isNaN(row)) {
            _row = row;
        }

        _audio.position(_row / ROW_RATE);

        loop();
    }

    function onPlay() {
        _audio.volume(AUDIO_VOLUME);
        _audio.position(_row / ROW_RATE);
        _audio.play();
        loop();
    }

    function onPause() {
        _audio.pause();

        _row = _audio.position() * ROW_RATE;
    }

    function loop() {

        var position = _audio.position();

        if (_audio.isPaused() === false) {
            window.requestAnimationFrame(loop, document);
            _syncDevice.update(position * ROW_RATE);
        }

        if (position < _audio.duration()) {
            _sceneList.update(position);
        }
    }

    function pause(setPaused) {

        if ((setPaused === true) && (!_audio.isPaused())) {
            _audio.pause();
        } else if (_audio.isPaused()) {
            _audio.play();
            loop();
        }
    }

    function onPreflightDone() {
        _readyToRoll = true;

        _audio.play();
    }

    function getAudio() {
        return _audio;
    }

    function getSceneList() {
        return _sceneList.getList();
    }

    function getModel() {
        return _model;
    }

    function getSceneListClass() {
        return _sceneList;
    }

    return {
        pause          :pause,
        start          :start,
        audio          :getAudio,
        sceneList      :getSceneList,
        model          :getModel,
        sceneController:getSceneListClass
    };
}());
