/**
 * Page - very main javascript object to manage most of behaviour
 * of ITzone website
 *
 * @author XShady
 * @project itzone
 */
 
var Page = {
	/**
	 * Method for basic page initializations
	 *
	 */
	init: function()
    {
		this.onLoadEvents = [];
		this.onElmRenderEvents = [];
		this.isAllRendered = false;
		this.renderCheckTimeout = 5000;
		this.timers = [];
		this.heartBeat = 250;
		this.date = new Date();
		this.time = 0;
		this.timeDiff = 0;
		this.debug = false;

		// Start main loop
		this.interval = setInterval('Page.loop()', this.heartBeat);
	},

	/**
	 * This method is called when page is all loaded
	 *
	 */
	onLoad: function()
    {
        for (var i = 0; i < this.onLoadEvents.length; i++)
        {
            eval(this.onLoadEvents[i]);
		}
		
		// Some period of time after all page is loaded is very likely
		// all elements are really rendered, if not, launch last actions
		// binded to onRender events and stop checking
		this.setTimer('Page.setAllElmsRendered()', this.renderCheckTimeout);
	},

	/**
	 * Method to add callback for page's onLoad event
	 *
	 */
	callOnLoad: function(code)
	{
		this.onLoadEvents[this.onLoadEvents.length] = code;
	},

	/**
	 * Method to add callback called when specified element appears on page
	 *
	 */
	callOnElementRender: function(code, elementId)
	{
		this.onElmRenderEvents[this.onElmRenderEvents.length] = {
			code: code,
			elementId: elementId,
			rendered: false
			};
	},
	
	/**
	 * Checks whether DOM element is rendered by browser
	 *
	 */
	isElmRendered: function(elementId)
	{
	    var element = document.getElementById(elementId);

		if (!element)
		    return false;
		
		return (element.offsetWidth && element.offsetHeight);
	},
	
	/**
	 * Goes through array with elements to check and checks them
	 *
	 */
	checkElmRenderEvents: function()
	{
		for (var i = 0; i < this.onElmRenderEvents.length; i++)
		{
		
		    if (this.onElmRenderEvents[i].rendered)
		        continue;

			if (this.isElmRendered(this.onElmRenderEvents[i].elementId))
			{
   				this.setTimer(this.onElmRenderEvents[i].code, this.heartBeat);
       			this.onElmRenderEvents[i].rendered = true;
			}
		}
	},
	
	/**
	 * This function suppose everything is alredy rendered, even if
	 * check failed. It's called usualy after longer time after page is loaded
	 *
	 */
	 setAllElmsRendered: function()
	 {
	    for (var i = 0; i < this.onElmRenderEvents.length; i++)
		{
		    if (!this.onElmRenderEvents[i].rendered)
		    {
		    	this.setTimer(this.onElmRenderEvents[i].code, this.heartBeat);
   				this.onElmRenderEvents[i].rendered = true;
			}
		}
	    this.isAllRendered = true;
	 },

	/**
	 * Sets internal page's interval
	 *
	 */
	setInterval: function(code, interval)
	{
	    this.timers[this.timers.length] = {
			code: code,
			interval: interval,
			lastTime: new Date().getTime(),
			repeat: true
			};
	    
	    return this.timers.length - 1;
	},
	
	/**
	 *	Removes interval from a queue
	 *
	 */
	clearInterval: function(index)
	{
	    delete this.timers[index];
		this.timers[index] = null;
	},
	
	/**
	 * Creates single timer
	 *
	 */
	setTimer: function(code, interval)
	{
		this.timers[this.timers.length] = {
			code: code,
			interval: interval,
			lastTime: new Date().getTime(),
			repeat: false
			};

	    return this.timers.length - 1;
	},
	
	/**
	 * Method to remember server-side time for further use
	 *
	 */
    setServerTime: function(hours, minutes, seconds)
    {
        var serverDate = new Date();
		serverDate.setHours(hours, minutes, seconds);

		var serverTime = serverDate.getTime();
        var clientTime = new Date().getTime();

        this.timeDiff = serverTime - clientTime;
	},
	
	/********
	 * DEPRECATED - will go away soon after change in header template on life ver
	 ********/
	setTime: function(hours, minutes, seconds)
	{
		this.setServerTime(hours, minutes, seconds);
	},
	
	/**
	 * This method returns supposed actual server time
	 *
	 */
	getServerTime: function()
	{
		return new Date().getTime() + this.timeDiff;
	},

	/**
	 * Assigns event listener for DOM element
	 *
	 */
    addEvent: function(id, evname, code)
	{
        var el = document.getElementById(id);
		if (el === null)
		    return false;

		var fname = 'el.on' + this.capitalize(evname);
		evname = evname.toLowerCase();

		// Create onEvent function of element
		eval(fname + ' = function() { ' + code + ' }');

		// Set that funct. as event listener
		if (el.attachEvent) { // IE
			eval('el.attachEvent("on' + evname + '", ' + fname + ')');
		} else if (el.addEventListener) { // Gecko / W3C
			eval('el.addEventListener("' + evname + '", ' + fname + ', true)');
		} else {
			eval('el[on' + evname + '] = "' + fname + '"');
		}
	},
	
	/**
	 * Abstraction of functions from old ITzone version in old.js,
	 * old.js is just temporary solution for my shortage of time,
	 * CODE SHALL BE INCLUDED HERE L8R
	 *
	 */
	hide: function(id) { Hide(id); },
	show: function(id) { Show(id); },
	showHide: function(id) { showHide(id); },

	/**
	 * Changes first char to uppercase, rest to lower
	 *
	 */
	capitalize: function(str) {
	    return str.charAt(0).toUpperCase() + str.substring(1).toLowerCase();
	},
	
	/**
	 * Returns DOM element, like shortcut for getElementById(),
	 * but also adds some other methods
	 *
	 */
	e: function(id)
	{
	    var el = document.getElementById(id);
	    if (!el)
	    {
	        if (this.debug)
	    		window.alert('Page: DOM element ' + id + ' does not exist, but is required by script to operate');
	        return false;
		}

		// Link to element some handy functions
		el.addEvent = function(a, b) { return Page.addEvent(id, a, b); }
		el.hide = function(a, b) { return Page.hide(id); }
		el.show = function(a, b) { return Page.show(id); }
		el.showHide = function(a, b) { return Page.showHide(id); }

		return el;
	},

	/**
	 * Main loop
	 *
	 */
	loop: function()
	{
	    var time = new Date().getTime();

		// Get through array with timers and eventually launch them
	    for (var i = 0; i < this.timers.length; i++)
	    {
			//if (this.timers[i] !== null)
       		//	window.alert('ss' + i + ':' + time + '>' + this.timers[i].lastTime);

	        if ((this.timers[i] !== null)
				&& (time >= this.timers[i].lastTime + this.timers[i].interval))
	        {
	            var code = this.timers[i].code;

	            if (this.timers[i].repeat)
	            	this.timers[i].lastTime = time;
				else
				    this.clearInterval(i);
				    
                eval(code); 
			}
		}

		// Check rendered state of elements if page is not all loaded
		//// XS: NOTE for vl4kn0: After first publishing it was all fucked up,
		// because of strange behaviour - after i recieved onLoad event of
		// page body i supposed all elements are alredy rendered, but thats
		// pure bullshit, u can't really trust that!
		// We just have to keep checking properly by ourselves...
		if (!this.isAllRendered)
		{
			Page.checkElmRenderEvents();
		}
	}
}

// Initialize whole page object as soon as possible
Page.init();