if (!SN.Time) {
	SN.Time = new Object();
}

SN.Time.TimeManager = new Object();
SN.Time.TimeManager.timer = null;
SN.Time.TimeManager.delay = 20;
SN.Time.TimeManager.lowestDelay = 20;
SN.Time.TimeManager.hasAnims = false;
SN.Time.TimeManager.playing = false;
SN.Time.TimeManager.inheritFrom = SN.Events.EventDispatcher;
SN.Time.TimeManager.inheritFrom();
// Now Animation is a static class version of EventDispatcher!
// Terribly exciting!

// Let's start with the controls..
SN.Time.TimeManager.start = function(offset) {
    if (!SN.Time.TimeManager.hasAnims) {
        // We don't have any animations!
        return;
    }
    SN.Time.TimeManager.playing = true;
    /* Every 17 milliseconds we attempt to create a "frame"... approx. 58.8
    times a second.  If there's an offset, we reduce the amount of time we wait
    to call the function again! */
    if (!offset) {
        offset = 0;
    }
    SN.Time.TimeManager.delay = Math.max(1, 20 - offset);
    SN.Time.TimeManager.lowestDelay = Math.min(SN.Time.TimeManager.lowestDelay, SN.Time.TimeManager.delay);
    SN.Time.TimeManager.timer = setTimeout("SN.Time.TimeManager.onEnterFrame()", SN.Time.TimeManager.delay);
};

SN.Time.TimeManager.stop = function() {
	SN.Time.TimeManager.playing = false;
	SN.Time.TimeManager.dispatchEvent('onclear', {});
};

SN.Time.TimeManager.nextFrame = function() {
	if (!SN.Time.TimeManager.playing) {
		SN.Time.TimeManager.onEnterFrame();
	}
};

// The master function
SN.Time.TimeManager.onEnterFrame = function() {
	var start = (new Date()).getTime();
	// Now we simply dispatch the event
	SN.Time.TimeManager.dispatchEvent('onenterframe', {'time':start});
	// Now we've called all the crazy functions!  Shall we call again?
	if (SN.Time.TimeManager.playing) {
		// The manager has neither been manually stopped nor has it been
		// stopped because no more listeners exists!
		SN.Time.TimeManager.start((new Date()).getTime() - start);
	} else {
		clearTimeout(SN.Time.TimeManager.timer);
		SN.Time.TimeManager.timer = null;
	}
};

// Listeners
SN.Time.TimeManager.addEventListener('eventadded', function listener(e) {
	if (e.type == 'onenterframe') {
		SN.Time.TimeManager.hasAnims = true;
		SN.Time.TimeManager.start();
	}
});

SN.Time.TimeManager.addEventListener('eventcleared', function listener(e) {
	if (e.type == 'onenterframe') {
		SN.Time.TimeManager.hasAnims = false;
		SN.Time.TimeManager.stop();
	}
});

/* Time Managing functions! */
SN.Time.TimeManager.stall = function(frames, afterWait) {
    var home = this;

    var waiter = 0;

    var listener = SN.Time.TimeManager.addEventListener('onenterframe', function stall(e) {
        if (waiter >= frames) {
            waiter = 0;
            SN.Time.TimeManager.removeEventListener('onenterframe', listener);
            //home.cancel();
            afterWait();
        } else {
            waiter++;
        }
    });

    this.cancel = function() {
        waiter = 0;
        SN.Time.TimeManager.removeEventListener('onenterframe', listener);
    };
};

// Add more functions here if need be!
