//Copyright 2011, Al Tenhundfeld
//Feel free to reuse and modify, but please keep reference to tenhundfeld.org

//Based on algorithm by Ray Norrish from the now defunct website:
//http://norrish.force9.co.uk/numberOfNodesiga

//NOTE: This is implemented with jQuery for easy element selection, append, extend, css.
//That dependency could be removed, but I already have that dependency in my context.

var danceParty = (function() {

    //setup default options
    var defaults = {
        containerElementSelector : '#norrish-image-container',

        imageUrl : 'images/acorn_16_light_beige_trans.png',
        imageWidth : 15,
        imageHeight : 16,

        numberOfNodes : 10,
        originX : 0,
        originY : 400,
        radius : 200,
        autoAdvance : false,

        interval : 15 //TODO: Move interval to currentState and add changeSpeed method to allow changing speed after init
    };

    //holds options passed into init or the default values
    var options = {};

    //Contains current state
    var currentState = {
        x : 0,
        y : 0,
        radius : 0,
        degree : 0,
        offset : 0,
        theta : 0,
        autoAdvance : false
    };

    /// Private Functions ///

    //Get the image URL for the index
    function getImageUrl(idx) {
        return options.imageUrl;

        //NOTE: This function was originally used to let me mix in a variety of images.
        // I found a single image made a better visual, but I left this hook in place to remind me of the idea.
        //    if ((idx % 2) === 0)
        //        return image_2_url
        //    else
        //        return image_1_url;
    }

    /// Public Functions ///

    //Initialize the animation
    var init = function(initOptions) {

        // Overwrite default options
        // with user provided ones
        // and merge them into "options".
        options = $.extend({}, defaults, initOptions);

        currentState.autoAdvance = options.autoAdvance;

        var elementsToInsert = "";
        for (var i = 0; i < options.numberOfNodes; i++) {
            elementsToInsert += '<div id="node' + i + '" style="position:absolute;top:0px;left:0px; width:' + options.imageWidth + 'px; height:' + options.imageHeight + 'px;">';
            elementsToInsert += '<img src="' + getImageUrl(i) + '" width=' + options.imageWidth + ' height=' + options.imageHeight + '>';
            elementsToInsert += '</div>';
        }

        $(options.containerElementSelector).append(elementsToInsert);

        var x = options.originX + options.radius * 1.5;
        var y = options.originY + options.radius;
        danceParty.advanceFrame(x, y, options.radius, 0.01, -0.06);
    };

    //Advances all nodes 1 frame
    var advanceFrame = function(currentX, currentY, radius, degree, offset) {
        currentState.theta += degree;
        var difference = 0;
        for (var i = 0; i < options.numberOfNodes; i++) {
            var $node = $('#' + "node" + i);
            var m1 = currentState.theta * difference;
            var m2 = currentState.theta + (difference / degree);
            var j1 = (parseInt(radius * Math.cos(m1)) + currentX) * 1.5;
            var j2 = parseInt(radius * Math.sin(m2)) + currentY;

            $node.css({left:j1, top:j2});
            difference -= offset;
        }
        currentState.x = currentX;
        currentState.y = currentY;
        currentState.radius = radius;
        currentState.degree = degree;
        currentState.offset = offset;

        if (currentState.autoAdvance) {
            setTimeout(function() {
                danceParty.advanceFrame(currentState.x, currentState.y, currentState.radius, currentState.degree, currentState.offset);
            }, options.interval);
        }
    };

    //Switches between auto-advance mode and manual mode
    var toggleAutoAdvance = function() {
        if (currentState.autoAdvance) {
            currentState.autoAdvance = false;
        } else {
            currentState.autoAdvance = true;
            danceParty.advanceFrame(currentState.x, currentState.y, currentState.radius, currentState.degree, currentState.offset);
        }
    };

    //Return an object with public methods/fields. #RevealingModulePattern
    return {
        options: options,
        init:init,
        advanceFrame:advanceFrame,
        toggleAutoAdvance:toggleAutoAdvance
    };

})();










