var slider_class = function (element, closed) {
	if (element === undefined)
		alert ("ELEMENT DOESNT exist");
	
	var self = this;
	var speed = 10;
	var friction = 0.0161;
	var offsetHeight = 0;
	this.init = function () {
		
		offsetHeight = element.offsetHeight;
		speed += Math.ceil((offsetHeight / speed) * friction);
		element.style.overflow 	= "hidden";
		if (closed)
			this.closeEnd();
		else
			this.openEnd();
	
	};
	var i = "";
	this.open = function (onFinish, onStep) {
		if (onFinish === undefined)
			onFinish = function () {};
		if (onStep === undefined)
			onStep = function () {};
		endTimer();
		var _friction 	= friction;
		var _speed		= speed;
		element.style.display = "";
		i = window.setInterval(function () {
			_speed 	-= _friction;
			var height = parseFloat(element.style.height);
			if ((height + _speed) > offsetHeight)
			{
				self.openEnd();
				endTimer();
				onFinish();
			}
			else
			{
				element.style.height = (height + _speed) + "px";
				onStep(_speed);
			}
		}, 20);
	};
	
	this.close = function (onFinish, onStep) {
		if (onFinish === undefined)
			onFinish = function () {};
		if (onStep === undefined)
			onStep = function () {};
		endTimer();
		var _friction 	= friction;
		var _speed		= speed;
		i = window.setInterval(function () {
			_speed 	-= _friction;
			var height = parseFloat(element.style.height);
			if (isNaN(height))
			{
				offsetHeight = element.offsetHeight;
				height = offsetHeight;
			}
			if ((height - _speed) < 0)
			{
				self.closeEnd();
				endTimer();
				onFinish();
			}
			else
			{
				element.style.height = (height - _speed) + "px";
				onStep(_speed);
			}
		}, 20);
	};
	var endTimer = function () {
		if (i !== "")
			window.clearInterval(i);
		i = "";
	};
	this.openEnd = function () {
		element.style.height	= "auto";
	};
	this.closeEnd = function () {
		element.style.height 	= "0px";
		element.style.display	= "none";
	};
	
	this.init();
};

function dragObject_class (element, dragElement) {
	var self = this;
	if (dragElement === element)
		dragElement = element;
	
	var onMouseEvent;
	this.init = function () {
		var onDragTimer;
		var onDblTimer;
		var clicks = 0;

		var drag = false;
		dragElement.onmousedown = function (e) {
			if (e === undefined)
				e = window.event;
			
			startX = e.clientX - element.offsetLeft;
			startY = e.clientY - element.offsetTop;
			onDragTimer = setTimeout(function () {
				drag = true;
				self._onDrag(startX, startY);
				onDragTimer = undefined;
				clearTimeout(onDblTimer);
			}, 200);
		};
		
		dragElement.onmouseup = function () {
			
			if (!drag)
				onclick();
		};
		dragElement.ondragstart = function () { return false; };
		
		var onclick = function () {
			if (clicks === 0)
			{
				self.onClick();
				onDblTimer = setTimeout (function () {
					clicks = 0;
				}, 180);
			}
			else if (clicks === 1)
			{
				self.onDblClick();
				clearTimeout(onDblTimer);
				clicks = -1;
			}
			clicks++;
		};
		
		
		main.events.onmouseup.addEvent(function (e) {
			if (drag)
			{
				self._onRelease(e.clientX, e.clientY);
				drag = false;
			}
			clearTimeout(onDragTimer);
		});
		
		element.onmousedown = function (e) {
			if (e.target === this || e.target === dragElement)
				self.onFocus();
		};
	};
		
	this._onDrag = function (startX, startY) { 
		if (this.onDrag() !== false)
		{
			onMouseEvent = main.events.onmousemove.addEvent(function (x, y) {
				element.style.marginLeft = x - startX + 'px';
				element.style.marginTop = y - startY + 'px';
			});
		}
	};
	this._onRelease = function (x, y) {
		if (this.onRelease(x, y, element.offsetLeft, element.offsetTop) !== false)
		{
			main.events.onmousemove.delEvent(onMouseEvent);
		}
	};
	
	this.onDrag = function () { };
	this.onRelease = function () { };
	this.onClick = function () { };
	this.onDblClick = function () { };
	this.onFocus = function () { };
	
	this.init();
};

function menu_class (appendTo) {
	var container;
	var activeHead;
	var items = new Array();
	this.init = function () {
		container = document.createElement("ul");
		container.className = 'menuContainer';
		appendTo.appendChild(container);
	};
	
	this.addChild = function (parent, data, onclick) {
		if (parent === undefined)
			parent = 0;
		
		var index = items.length;
		items[index] = data;
		items[index]['onclick'] = (onclick === undefined)? function () {} : onclick;
		items[index]['parent'] = parent;
		
	};
	var linkClick = false;
	this.render = function (parent, append, level) {
		
		if (parent === undefined)
		{
			parent = null;
			level = 0;
		}
		if (append === undefined)
		{
			container.innerHTML = "";
			append = container;
		}
		var li, ul;
		for (var i = 0; i < items.length; i++)
		{
			if (items[i]['parent'] === parent)
			{
				items[i]['li'] = document.createElement("li");
				append.appendChild(items[i]['li']);
				
				items[i]['a'] = document.createElement("link");
				items[i]['a'].href= items[i]['href'];
				items[i]['a'].innerHTML = items[i]['name'];
				
				items[i]['li'].appendChild(items[i]['a']);
				items[i]['ul'] = document.createElement("ul");
				if (parent === null)
					items[i]['ul'].style.position = "absolute";
				items[i]['li'].appendChild(items[i]['ul']);
				
				this.render(i, items[i]['ul'], (level + 1));
				
				items[i]['li'].rel = i;
				items[i]['ul'].rel = i;
				items[i]['a'].rel = i;
				items[i]['parent'] = parent;
				items[i]['level'] = level;
				items[i]['activeLink'];
				items[i]['animation'] = new main.animation.slider(items[i]['ul'], true);
				
				items[i]['a'].onclick =  function (e) {
					linkClick = true;
					if (e.target === this)
					{
						if (items[this.rel]['parent'] === null)
						{
							if (activeHead !== undefined)
								items[activeHead]['animation'].close();
							if (activeHead === this.rel)
							{
								activeHead = undefined;
								items[this.rel]['animation'].close();
							}
							else
							{
								activeHead = this.rel;
								items[this.rel]['animation'].open();
							}
							
						}
						else
						{
							if (items[items[this.rel]['parent']]['activeLink'] !== undefined)
								items[items[items[this.rel]['parent']]['activeLink']]['animation'].close();
							if (items[items[this.rel]['parent']]['activeLink'] === this.rel)
							{
								items[items[this.rel]['parent']]['activeLink'] = undefined;
								items[this.rel]['animation'].close();
							}
							else
							{
								items[items[this.rel]['parent']]['activeLink'] = this.rel;
								items[this.rel]['animation'].open();
							}
						}
					}
					return items[this.rel]['onclick']();
				};
				
			}
		}
		if (parent === 0)
		{
			main.events.onclick.addEvent(function (e) {
				if (!linkClick)
				{
					if (activeHead !== undefined)
					{
						items[activeHead]['animation'].close();
						activeHead = undefined;
					}
					
				}
				linkClick= false;
			});
		}
		var clear = document.createElement("div");
		clear.style.clear = "both";
		append.appendChild(clear);
	};
	this.init();
};

function tabMenu_class (menu) {
	var menuItems = new Array();
	this.addTab = function (tabName, tab, selected) {
		if (selected === null)
			selected = false;
			
		var index = menuItems.length;
		menuItems[index] = new Array();
		menuItems[index]['listItem'] 	= document.createElement("li");
		menuItems[index]['div']			= tab;
		menuItems[index]['default']		= selected;
		menuItems[index]['animation']	= new main.animation.slider(tab, !selected);
		var tabItem = menuItems[index]['listItem'];
		
		tabItem.innerHTML = tabName;
		tabItem.rel = index;
		tabItem.onclick = function () {
			for (var i = 0; i < menuItems.length; i++)
			{
				if (i === this.rel)
				{
					//this is the selected tab
					menuItems[i]['animation'].open();
					menuItems[i]['listItem'].className = "tabActive";
				}
				else
				{
					//this is te rest!
					menuItems[i]['animation'].close();
					menuItems[i]['listItem'].className = "tab";
				}
			}
		};
	};
	
	this._render = function () {
		var defaultIndex = "";
		for (var i = 0; i < menuItems.length; i++)
			if (menuItems[i]['default'])
				defaultIndex = i;
				
		for (var i = 0; i < menuItems.length; i++)
			menu.appendChild(menuItems[i]['listItem']);
		
		if (defaultIndex != "")
		menuItems[defaultIndex]['listItem'].onclick();
		
		var clearli = document.createElement("div");
		clearli.className = "cleardiv";
		menu.appendChild(clearli);
	};
};

var window_controller = new function () {
	var windows = new Array();
	var selectedWindow;
	var container;
	var self = this;
	this.setContainer = function (_container) {
		container = _container;
	};
	
	this.dellWindow = function (index) {
		if (container !== undefined)
		{
			try {
				windows.splice(index, 1);
			} catch (e) {
				alert("cannot kill progress..");
				//console.log(e);
				return false;
			}
		}
		return false;
	};
	
	this.addWindow = function (windowTitle, drawFunction, args) {
		if (container !== undefined)
		{
			var index = windows.length;
			windows[index] = new window_class(container, windowTitle, drawFunction, args);
			windows[index].windowArrayIndex = index;
			windows[index].setIndex(index);
			windows[index].__onFocus = function () {
				var index = this.getIndex();
				if (index + 1 !== windows.length)
				{
					for (var i = 0; i < windows.length; i++)
					{
						if (windows[i].getIndex() > index)
						{
							if (windows[i].getIndex() + 1 === windows.length)
								var selectedIndex = i;
							windows[i].setIndex((windows[i].getIndex() - 1));
						}
						
						
					}
					windows[selectedIndex].onUnFocus();
					this.setIndex(windows.length -1);
					this.onFocus();
				}
			};
			windows[index].__onClose = function () {
				self.dellWindow(this.windowArrayIndex);
			};
			
			return windows[index];
		}
	};
	
	var window_class = function (appendTo, windowTitle, drawFunction, args) {
		var self = this;
		this.header;
		this.content;
		this.init = function () {
			this.header = document.createElement("div");
			this.content	 = document.createElement("div");
			
			this.header.className = 'window';
			this.content.className = 'header';
			this.header.appendChild(this.content);
			appendTo.appendChild(this.header);

			var dragUI = new main.ui.dragObject(this.header, this.content);
			dragUI.onDrag = function () {
				if (self.header.style.width === "100%")
					return false;
				self.content.className = 'headerSelected';
				self.onDrag();
			};
			
			var divXpos		= 0;
			var divYpos		= 0;
			
			dragUI.onRelease = function (mouseX, mouseY, divX, divY) {
				if (self.header.style.width === "100%")
					return false;
				divXpos = divX + 'px';
				divYpos = divY + 'px';
				self.content.className = 'header';
			};
			
			dragUI.onDblClick = function () {
//				if (self.header.style.width === "100%")
//				{
//					self.header.style.width 		= "";
//					self.header.style.height		= "";
//					self.header.style.marginTop 	= divYpos;
//					self.header.style.marginLeft 	= divXpos;
//					self.onMaximize();
//				}
//				else
//				{
//					self.header.style.width 		= "100%";
//					self.header.style.height 		= "100%";
//					self.header.style.margin		= "0px";
//					self.onMinimize();
//				}
			};
			
			dragUI.onFocus = function () {
				self.focus();
			};
			
			this.content.appendChild(document.createTextNode(windowTitle));
			var href = document.createElement("a");
			href.href= '#';
			href.className = 'close';
			href.innerHTML = 'X';
			href.onclick = function () {
				self.onClose();
				self.close();
				return false;
			};
			this.content.appendChild(href);
			
			var content = document.createElement("div");
			this.header.appendChild(content);
			drawFunction(args, content);
		};
		this.close = function () {
			this.header.innerHTML = '';
			
			appendTo.removeChild(this.header);
			
			
			this.onClose();
			this.__onClose();
		};
		
		this.onClose = function () { };
		this.onDrag = function () { };
		this.onUnFocus = function () { };
		this.onFocus = function () { };
		this.onMaximize = function () { };
		this.onMinimize = function () { };
		
		
		this.focus = function () {
			this.__onFocus();
			this.onFocus();
		};
		
		this.setIndex = function (index) {
			self.header.style.zIndex = index + 1;
			return true;
		};
		this.getIndex = function () {
			return parseInt(self.header.style.zIndex) - 1;
		};
		
		this.init();
	};
}();

function animation_class () {
	this.slider = slider_class;
	
}

function event_class (main) {
	var events = new Array();
	this.callEvent = function (a, b, c, d, e, f, g, h, i, j) {
		for (var i = 0; i < events.length; i++)
			events[i](a, b, c, d, e, f, g, h, i, j);
	};
	
	this.addEvent = function (func) {
		var index = events.length;
		events[index] = func;
		return index;
	};
	
	this.delEvent = function (index) {
		events.splice(index, 1);
	};
};

function events_class () {
	var self = this;
	
	this.onload = new event_class();
	this.onclick = new event_class();
	this.onURLchange = new event_class();
	this.onmousemove = new event_class();
	this.onmouseup = new event_class();
	
	window.onload = function () {
		document.body.onclick = function (e) { 
			if (e === undefined)
				e = window.event;
			self.onclick.callEvent(e); 
		};
		self.onload.callEvent();
		
		var url = "";
		var interval = function () {
			if (url !== "" + window.location)
			{
				url = "" + window.location;
				var etc = url.split("#");
				self.onURLchange.callEvent(etc[1]);
			}
		};
		window.setInterval(interval, 20);
		interval();
		
		document.body.onmousemove = function (e) {
			if (e === undefined)
				e = window.event;
			self.onmousemove.callEvent(e.clientX, e.clientY);
		};
	};
	
	document.onmouseup = function (e) {
		if (e === undefined)
			e = window.event;
		self.onmouseup.callEvent(e);
	};
};

function history_class (main) {
	var self = this;
	var arrayIndexes	= new Array();
	var arrayFunctions 	= new Array();
	var arrayData 		= new Array();
	this.activeHandler;
	main.events.onURLchange.addEvent(function (arg) {
		this.activeHandler = arg;
		var handlerID = getFunctionIndex(arg);
		if (handlerID !== false)
			arrayFunctions[handlerID](arrayData[handlerID]);
		else
			self.defaultHandler(arg);
	});
	
	
	this.addHandler = function (index, func, args) {
		if (args === undefined)
			args = new Array();
		arrayIndexes[arrayIndexes.length] 		= index;
		arrayFunctions[arrayFunctions.length]	= func;
		arrayData[arrayData.length]				= args;
	};
	
	this.dropHandler = function (index) {
		var handlerID = getFunctionIndex(index);
		if (handlerID !== false)
		{
			arrayIndexes.splice(handlerID, 1);
			arrayFunctions.splice(handlerID, 1);
		}
	};
	
	this.dropHandlers = function (index) {
		var arrayIndexes	= new Array();
		var arrayFunctions 	= new Array();
		var arrayData 		= new Array();
	};
	
	this.defaultHandler = function () { };
	
	var getFunctionIndex = function (arg) {
		var available = false;
		for (var i = 0; i < arrayIndexes.length; i++)
			if (arrayIndexes[i] == arg)
				available = i;
		return available;
	};
	
	this.call = function () {
		url = "" + window.location;
		var etc = url.split("#");
		main.events.onURLchange.callEvent(etc[1]);
	};
	
};

function ui_class (main) {
	this.tabMenu = tabMenu_class;
	this.menu = menu_class;
	this.dragObject = dragObject_class;
};

var main = new function () {
	var self 		= this;
	this.events 	= new events_class(self);
	this.history 	= new history_class(self);
	this.animation 	= new animation_class(self);
	this.ui			= new ui_class(self);
}();
