﻿// by Lincoln! 1.1

function frotator(parent) {


    /* ------------------------- settings ------------------------- */
    var VISIBLE_TIME_SECS = 3;
    /* ------------------------------------------------------------ */


    if (!this instanceof frotator) {
        return new frotator(parent);
    }

    // private:
    var ActionState = {
        HOLD: 0,
        FADEOUT: 1,
        FADEIN: 2
    };

    var _parent = parent;
    var ids = [];
    var elements = [];
    var cursor = 0;
    var framesInSequence = 15;
    var delay = VISIBLE_TIME_SECS * 1000;
    var interval = 1000 / 30;
    var timerID = 0;
    var count = 0;

    var state = ActionState.HOLD;
    var _changeState = null;



    function init() {
        if (!_parent) { return; }
        var ps = _parent.getElementsByTagName('p');
        var opacity = 1;
        for (var j = 0, len = ps.length; j < len; j++) {
            elements.push(ps[j]);
            setOpacity(ps[j], opacity);
            opacity = 0;
        }
    }

    // helper function for css opacity
    function setOpacity(element, fraction) {
        element.style.opacity = fraction.toString();
        element.style.filter = 'alpha(opacity=' + Math.round(fraction * 100).toString() + ')';
    }




    // processing loop
    function proc() {
        var now = new Date();
        if (state === ActionState.FADEOUT) {
            var opacity = ++count / framesInSequence; // get opacity value in the range of 0-1 (counts up)

            setOpacity(elements[cursor], 1 - opacity);   // fading out

            if (count >= framesInSequence) {
                count = 0;   // reset
                cursor = (cursor + 1) % elements.length; // move up the array
                state = ActionState.FADEIN;
            }
        }
        else if (state === ActionState.FADEIN) {
            var opacity = ++count / framesInSequence; // get opacity value in the range of 0-1 (counts up)

            setOpacity(elements[(cursor)], opacity);  // fading in

            if (count >= framesInSequence) {
                count = 0;   // reset
                state = ActionState.HOLD;
                _changeState = new Date(now.getTime() + delay);
            }
        }
        else if (state === ActionState.HOLD) {
            if (_changeState && now > _changeState) {
                state = ActionState.FADEOUT;
                _changeState = null;
            }
        }

    }


    // public:
    //    this.add = function(id) {
    //        ids.push(id);
    //    };

    this.start = function() {
        if (!_parent) { return false; }

        timerID = setInterval(proc, interval); // start the processing loop

        if (!_changeState) {
            _changeState = new Date((new Date()).getTime() + delay);
        }

        return true;
    };

    this.stop = function() {
        if (!_parent) { return false; }

        clearInterval(timerID);
        _changeState = null;
        return true;
    };


    init();
}

