/* 
	Contains all elements
*/
function mainElement() {
	
	// array containing all elements id is the key
	this.arrElement = new Array();
	
	// function for getting element
	this.get = function (objRef) {
		
		// check if objRef is string or object
		if(typeof(objRef) == 'string') {
			
			
			
			// does object exist form previously
			if(this.arrElement[objRef]) {
			
				// make a new element - transfer vars
				var tmpOldElm = this.arrElement[objRef];
				this.arrElement[objRef] = new element(objRef);
				
				this.arrElement[objRef].arrMouseMove = tmpOldElm.arrMouseMove;
				this.arrElement[objRef].arrOnResize = tmpOldElm.arrOnResize;
				this.arrElement[objRef].attachedElm = tmpOldElm.attachedElm;
				this.arrElement[objRef].arrOnClick	= tmpOldElm.arrOnClick;
				this.arrElement[objRef].arrMouseOver= tmpOldElm.arrMouseOver;
				this.arrElement[objRef].arrCoords	= tmpOldElm.arrCoords;
				this.arrElement[objRef].fh			= tmpOldElm.fh;
				return this.arrElement[objRef];
			
			
				
			} else {
				// make a new element
				this.arrElement[objRef] = new element(objRef);
				return this.arrElement[objRef];
			}
			
		} else if(typeof(objRef) == 'object') {
			
			if(objRef.nodeName == "element") {
				
				return this.arrElement[objRef.id];
				
			}
			
			var newId = new Date();
			
			// check for id - if non set id = undefined
			
			var tmpObjId = (objRef.id == '' || typeof(objRef.id) == 'undefined')?objRef.nodeName + "_" + newId.getMilliseconds():objRef.id;
			// does object exist form previously
			if(this.arrElement[tmpObjId] && tmpObjId != "NaN") {
				
				// is element still in DOM?
				if(this.arrElement[tmpObjId].obj == objRef && this.arrElement[tmpObjId].obj.parentNode) {
					
					
					return this.arrElement[tmpObjId];
					
				} else {
					
					// make a new element - transfer vars
					var tmpOldElm = this.arrElement[tmpObjId];
					this.arrElement[tmpObjId] = new element(objRef);
					this.arrElement[tmpObjId].arrMouseMove 	= tmpOldElm.arrMouseMove;
					this.arrElement[tmpObjId].arrOnResize 	= tmpOldElm.arrOnResize;
					this.arrElement[tmpObjId].attachedElm 	= tmpOldElm.attachedElm;
					this.arrElement[tmpObjId].arrOnClick	= tmpOldElm.arrOnClick;
					this.arrElement[tmpObjId].arrMouseOver	= tmpOldElm.arrMouseOver;
					this.arrElement[tmpObjId].arrCoords		= tmpOldElm.arrCoords;
					this.arrElement[tmpObjId].fh			= tmpOldElm.fh;
					return this.arrElement[tmpObjId];
				}
				
			} else {
				//alert(newId)
				// make a new element
				this.arrElement[tmpObjId] = new element(objRef);
				return this.arrElement[tmpObjId];
			}
		}
		
	}
	
	this.getElmByClassTagName = function (strClassName,tagName) {
		
		var elms = document.getElementsByTagName(tagName);
		var tmpElms = new Array();
		
       	for (var i=0;i<elms.length;i++) {
			if (elms[i].className==strClassName) {
				tmpElms[tmpElms.length] = this.get(elms[i]);
			}
       	}
       	
       	return tmpElms;
	}
	
	// attaching events
	this.attachEvent = function (arrElms,strType,eventRef) {
		
		for (var i=0;i<arrElms.length;i++) {
			
			if(arrElms[i].className != "noNode") {
				
				try {
					this.get(arrElms[i]).attachEvent(strType, eventRef);
				} catch (err) {}
			}
       	}
		
	}
	
	
	this.getCss	= function (obj,style) {
		return browser.IE?obj.currentStyle[style]:document.defaultView.getComputedStyle(obj,null).getPropertyValue(style);
		
	}
}


function element(objRef) {
	
	// defining variables
	this.nodeName 		= "element";
	this.arrMouseMove 	= new Array();
	this.arrOnResize	= new Array();
	this.arrOnClick		= new Array();
	this.arrMouseOver	= new Array();
	this.arrCoords		= new Array();
	this.attachedElm	= null;
	this.fh				= 0;
		
	// check if id is string or object
	if(typeof(objRef) == 'string') {
		this.id 	= objRef;
		this.obj 	= browser.DOM?document.getElementById(objRef):document.all[objRef];
	} else {
		this.obj 	= objRef;
		this.id 	= objRef.id;
	}
	
	
	
	if(this.obj) {
		// does element exist?
		if(this.obj.ref) {
			
			// restoring reference
			this.arrMouseMove 	= this.obj.ref.arrMouseMove;
			this.arrOnResize 	= this.obj.ref.arrOnResize;
			this.attachedElm	= this.obj.ref.attachedElm;
			this.arrOnClick		= this.obj.ref.arrOnClick;
			this.arrMouseOver	= this.obj.ref.arrMouseOver;
			this.arrCoords		= this.obj.ref.arrCoords;
			this.fh				= this.obj.ref.fh;
		} else {
			
			// create reference
			this.obj.ref = this;
		}
	} else {
		
		return false;
	}
	
	// does element exist?
	if(this.obj.ref) {
		
		// restoring reference
		this.arrMouseMove 	= this.obj.ref.arrMouseMove;
		this.arrOnResize 	= this.obj.ref.arrOnResize;
		this.attachedElm	= this.obj.ref.attachedElm;
		this.arrOnClick		= this.obj.ref.arrOnClick;
		this.arrMouseOver	= this.obj.ref.arrMouseOver;
		this.arrCoords		= this.obj.ref.arrCoords;
		this.fh				= this.obj.ref.fh;
	} else {
		
		// create reference
		this.obj.ref = this;
	}
	
	// if new init 
	if (this.obj) {
		this.style 	= 	this.obj.style;
		this.w 		= 	browser.DOM?this.obj.offsetWidth:this.style.pixelWidth;
		this.h 		= 	browser.DOM?this.obj.offsetHeight:this.style.pixelHeight;
		
		this.getElmByTagName = function (tagName,arrAllowedClasses) {
			
			// arrAllowedClasses - only som classes of tagname allowed
			if(typeof(arrAllowedClasses) != 'undefined') {
			
				var tmpElementArray = this.obj.getElementsByTagName(tagName);
				var tmpElementArrayReturn = new Array();
				
				// looping elements - checking className
				for (var i=0;i<tmpElementArray.length;i++) {
			
					// if in array add to element array
					if(in_array(tmpElementArray[i].className,arrAllowedClasses)) {
						
						tmpElementArrayReturn[tmpElementArrayReturn.length] = tmpElementArray[i];
						
					}
		       	}	
		       	
		       	return tmpElementArrayReturn;
		       	
			} else {
				
				// return all of tagname
				return this.obj.getElementsByTagName(tagName);
			
			}
		}
		
		this.getChildElms = function () {
			
			return this.obj.childNodes;
			
		}
		
		this.getChildElmsFilter = function (arrIgnoreTags,arrIgnoreClasses) {
			
			if(typeof(arrIgnoreClasses) == "undefined") {
				
				var arrIgnoreClasses = new Array();
				
			}
			
			var tmpArrElm = new Array();
			
			for(var x = 0;x < this.obj.childNodes.length; x++) {
				
				if(!in_array(this.obj.childNodes[x].nodeName,arrIgnoreTags) && !in_array(this.obj.childNodes[x].className,arrIgnoreClasses)) {
					
					tmpArrElm[tmpArrElm.length] = this.obj.childNodes[x];
					
				}
				
			}
			
			return tmpArrElm;
		}
		
		
		this.getCss	= 	function (style) {
			return browser.IE?this.obj.currentStyle[style]:document.defaultView.getComputedStyle(this.obj,null).getPropertyValue(style);
		
		}
		// gets object height
		this.getH 	= 	function () {
			return browser.DOM?this.obj.offsetHeight:this.style.pixelHeight;
		}
		
		// gets object inner height
		this.getIH 	= 	function () {

			return this.obj.clientHeight;
		}
		
		// gets object difference in inner height and height
		this.getDH 	= 	function () {

			return this.getH() - this.getIH();
		}
										
		// gets object width
		this.getW 	= 	function () {
			return browser.DOM?this.obj.offsetWidth:this.style.pixelWidth;
		}
		
		// gets object inner height
		this.getIW 	= 	function () {

			return this.obj.clientWidth;
		}
		
		// gets object difference in inner width and width
		this.getDW 	= 	function () {

			return this.getW() - this.getIW();
		}

		// shows object
		this.show 	= 	function () {
			
			if(this.style.display != "block") {
				this.style.display = "block";
			}
		}
		
		this.getDisplay = function() {
			return this.style.display; 
		}
		
		// hide object
		this.hide 	= 	function () {
			this.style.display = "none";
		}
		
		this.setH 	= 	function (height) {
			
			height = parseInt(height)<0?"0px":height;
			this.style.height  = height;
			
			this.resize();
		} 
						
		this.setW 	= 	function (width) {
			
			width = parseInt(width)<0?"0px":width;
			
			this.style.width = width;
			this.resize();
			
		}
		
		this.setLeft = 	function (left) {
			this.style.left = left;
			
		}
		
		this.setTop = 	function (top) {
			this.style.top = top;
			
		}
		
		this.getMT 	= 	function () { 
			if(this.style) {
				tempMT = parseInt(this.style.marginTop);
				return (isNaN(tempMT))?0:tempMT;
			}
		}
						
		this.getPT 	= 	function () { 

			if(this.style) {
				tempPT = parseInt(this.style.paddingTop);
				return (isNaN(tempPT))?0:tempPT;
			}				
		}
						
		this.getMB 	= 	function () { 
			
			if(this.style) {
				tempMB = parseInt(this.style.marginBottom);
				return (isNaN(tempMB))?0:tempMB;
			}
		}
		
		this.getPB 	= 	function () { 
			
			tempPB = parseInt(this.style.paddingBottom);
			return (isNaN(tempPB))?0:tempPB;
			
		}
		
		// offsetTopParent	
		this.getOP 	= 	function () { 
			

			var tmpParent = mainElm.get(this.obj.parentNode);
			
			return this.getY() - tmpParent.getY();
			
		}
		
		this.getPos = function () {
			
			var curleft = curtop = 0;
			
			var tmpObj = this.obj;
			
			if(typeof(tmpObj.offsetParent) == 'object' ) {
				if (tmpObj.offsetParent) {
					curleft = tmpObj.offsetLeft
					curtop = tmpObj.offsetTop
					
					while (tmpObj = tmpObj.offsetParent) {
						curleft += tmpObj.offsetLeft
						curtop += tmpObj.offsetTop
					}
				}
			}
			
			return [curleft,curtop];
		}
		
		this.getX = function () {
			
			var curleft = 0;
			
			var tmpObj = this.obj;
			
			if (tmpObj.offsetParent) {
				curleft = tmpObj.offsetLeft
				while (tmpObj = tmpObj.offsetParent) {
					curleft += tmpObj.offsetLeft
				}
			}
			
			return curleft;
		}
		
		this.getY = function () {
			
			var curtop = 0;
			
			var tmpObj = this.obj;
			
			if (tmpObj.offsetParent) {
				curtop = tmpObj.offsetTop
				while (tmpObj = tmpObj.offsetParent) {
					curtop += tmpObj.offsetTop
				}
			}
			return curtop;
		}
		
		
		this.sizeFromRef = function () {
			
			this.setH((this.attachedElm.getH() - 2) + "px");
			this.setW((this.attachedElm.getW() - 2) + "px");
		}
		
		this.attachOnResize = function (action,objRef) {
			
			var tmpId = 0;
			var tmpAction = action;
			
			// do we have an object or just an action
			if(typeof(objRef) == "object") {
				
				if(objRef.id) {
					tmpId = objRef.id
					// check if in mainEvt
					if(mainElm.arrElement[tmpId]) {
						tmpAction = "mainElm.get('" + tmpId + "')." + tmpAction;
					}
				}
				
			} 
			
			// does array exist
			if(!this.arrOnResize[tmpId]){
				this.arrOnResize[tmpId] = new Array();
			}
			
			this.arrOnResize[tmpId][action] = tmpAction;
			
			
		}
		
		
		
		// attaching events
		this.attachEvent = function (strType,abilityRef,forceRef) {
			
			if(typeof(forceRef) == "undefined") {
				forceRef = this;
				
			} 
			
			// attach event
			switch (strType) {
				
				case "mouseover":
				
					if(!this.arrMouseOver.length) {
						this.activateMouseOver();
					}
					
					// disabeling select
					this.obj.onmousedown = function () {
						return false;
					}
					
					if(typeof(abilityRef) == "string") {
						// check if ability is in fact a function call
						this.arrMouseOver[abilityRef] = abilityRef;
					} else {
						// check if ability is in fact a function call
						this.arrMouseOver[abilityRef.id] = [abilityRef,forceRef];
					}
				  break;
			
				case "mousemove":
					
					// attach to main event
					mainEvt.attachOnMove(this,abilityRef);
					
					break;
					
				case "mouseclick":
					
					mainEvt.attachOnClick(this,abilityRef);
					
				  break;
				  
				case "elmmouseclick":
					
					if(!this.arrOnClick.length) {
						this.activateMouseClick();
					}
				
					this.arrOnClick[abilityRef.id] = [abilityRef,forceRef];
				
					break;
					
				case "elmmousemove":
				
					if(!this.arrMouseMove.length) {
						this.activateMouseMove();
					}
				
					this.arrMouseMove[abilityRef.id] = abilityRef;
					
				  break;
				
			}
			
		}	
		
		this.dettachEvent = function (strType) {
			
			
			// attach event
			switch (strType) {
				
				case "mouseover":
				
					this.arrMouseOver = new Array();
					
					
				  break;
				  
				case "elmmouseclick":
					
					
					this.arrOnClick = new Array();
				
					break;
				
				
			}
			
		}
		
		// activation mouse over events
		this.activateMouseOver = function () {
			
			this.obj.onmouseover = function (e) {
				
				try {
					if(!mainEvt.isMouseDown) {
						
						// looping attached events
						for(key in this.ref.arrMouseOver) {
							
							
							var tmpRef = this.ref.arrMouseOver[key];
						
							// c heck if string
							if(typeof(tmpRef) == "string") {
								
								// preferre elements with coordinates
								eval(tmpRef + "(mainElm.get(this))");
								
							} else {
								// preferre elements with coordinates
								mainEvt.mouseLocked 		= 1;
								//mainEvt.attachOnDown(tmpRef,this.ref,"pointer",5);
								mainEvt.attachOnDown(tmpRef[0],tmpRef[1],"pointer",5);
								
							}
						}
					}
				} catch (err){
				
				}
			}
			
			this.obj.onmouseout = function (e) {
				
				
				try {
					// only detach if mouse is not down
					if(!mainEvt.isMouseDown) {
						mainEvt.detachOnDown();
					}
					mainEvt.mouseLocked = 0;
					mainEvt.mouseAbilityInside = 0;
				} catch (err){
					   
				}
				
			}
			
		}
		
		// activation mouseclick events
		this.activateMouseClick = function () {
	
			this.obj.onclick = function (e) {
				
				if(!browser.IE) {
										
					x = e.pageX;
					y = e.pageY;
					
				} else {
					
					x = window.event.clientX + document.documentElement.scrollLeft;
					y = window.event.clientY + document.documentElement.scrollTop;
					
				}
				
				// looping attached events
				for(key in this.ref.arrOnClick) {
					
					var tmpRef = this.ref.arrOnClick[key];
					
					if(tmpRef[0].run(tmpRef[1],x,y,1) || tmpRef[0].areaAll) {
						
						tmpRef[0].execute(tmpRef[1]);
						
						break;
					}
					
				}
				
			}
		}
		
		// activation mouseclick events
		this.activateMouseMove = function () {
			
			this.obj.onmousemove = function (e) {
				
				if(!mainEvt.isMouseDown) {
					if(!browser.IE) {
											
						x = e.pageX;
						y = e.pageY;
						
					} else {
						
						x = window.event.clientX + document.documentElement.scrollLeft;
						y = window.event.clientY + document.documentElement.scrollTop;
						
					}
					// looping attached events
					for(key in this.ref.arrMouseMove) {
						
						var tmpRef = this.ref.arrMouseMove[key];
						
						if(tmpRef.runCheck(this.ref,x,y)) {
							
							this.ref.obj.onmouseout();
							
							// preferre elements with coordinates
							mainEvt.mouseLocked 	= 1;
							mainEvt.attachOnDown(tmpRef,this.ref,"NW-resize",5);
							
							
						} else {
							
							this.ref.obj.onmouseover();
						}
						
					}
				}
			}
		}
		
		this.resize = function () {
			
			for(key in this.arrOnResize) {
				
				for(name in this.arrOnResize[key]) {
					
					try {
					
						eval(this.arrOnResize[key][name]);
					} catch (err) {
						
					}
				}
			}
			
		}
		
		this.reInitSqr = function () {
			
			// array for ability
			var tmpAbi = new Array();
			
			// loop coordinates
			while (this.arrCoords.length != 0 ) {
				
				tmpAbi[this.arrCoords.shift().remove()] = 1;
			}
			
			for(key in tmpAbi) {
				// resetting cords
				mainAbi.get(key).setCoords(this,mainEvt);
				
			}
			
		}
		
		// function for setting object position relative to another object 
		// x & y: offset position can be both pixel and percent
		this.setPR = function (objRef,x,y) {
			
			// attaching this relative element
			this.attachedElm = mainElm.get(objRef);
			// is obejct positioned absolute?
			if(this.getCss("position") != "absolute") {
				
				this.style.position = "absolute";
				
			}
			
			var left = 0;
			
			var re = new RegExp('%');
	
			// making left
			if(x.match(re)) {
				// using percent
				left = this.attachedElm.getX() + (this.attachedElm.getW() / x.substring(0,x.length-1)) * 100;	
				
			} else {
				
				// using pixels
				left = this.attachedElm.getX() + parseInt(x);
			}
			 
			
			// setting left position
			this.setLeft(left + "px");
			
			this.attachedElm.attachOnResize("setPR(this,'" + x + "','" + y + "')",this);
			
		}
		
		// function for setting 100% remaining width;
		this.setFW = function () {
			
			var	getOL		= 0;
			var tmpWidth	= 0;
			var	after		= 0;
			var ignoreId	= new Array();
			var ignoreIdJoin= new Array();
			
			for(var x = 0;x < arguments.length; x++) {
				
				ignoreId[arguments[x]] = 1;
				ignoreIdJoin[x] = "'" + arguments[x] + "'"; 
			}
			
			// we need to find all nodes in same level after the element and find their height
			for(var x = 0; x < this.obj.parentNode.childNodes.length; x++) {
				
				var tmpRef = mainElm.get(this.obj.parentNode.childNodes[x]);
				
				if(after && !ignoreId[tmpRef.id]) {
					
					// only objects 
					if(tmpRef.getW() > 0) {
						// check if element blocks
						if(getOL < tmpRef.getX()) {
							
							tmpWidth = tmpWidth + parseInt(tmpRef.getW());
						}
					}
					
				}
				
				// only find height if not objRef
				if(this.obj.parentNode.childNodes[x] == this.obj) {
					
					// is obejct positioned absolute?
					if(this.attachedElm) {
						// try to attach to assign element
						prevOL 		= this.attachedElm.getX() + this.attachedElm.getW();
						tmpWidth	= prevOL;
						after 		= 1;
						this.attachedElm.attachOnResize("setFW(" + ignoreIdJoin.join(",") + ")",this);
						
					} else {
						
						// setting tmpHeight = offset height
						prevOL 		= this.getX();
						tmpWidth	= prevOL + this.getDW();
						after 		= 1;
						
					}
					
					
				}
			}
			
			// getting parent
			var objParent = mainElm.get(this.obj.parentNode);
			
			// set height - tmpHeight
			this.setW(objParent.getW() - tmpWidth + "px");
				
			// attaching event to resize
			mainEvt.attachOnResize("setFW(" + ignoreIdJoin.join(",") + ")",this);
			
		}
		
		// function for setting 100% screen height;
		this.setFSH = function () {
			
			this.setH(browser.getPageSizeWithScroll()[1] + "px");
			
		}
		
		// function for setting 100% remaining height;
		this.setFH = function () {
			
			// setting object to full height status
			this.fh 		= 1;
			
			var	prevOP		= 0;
			var tmpHeight	= 0;
			var	after		= 0;
			
			// we need to find all nodes in same level after the element and find their height
			
			for(var x = 0; x < this.obj.parentNode.childNodes.length; x++) {
				
				var tmpRef = mainElm.get(this.obj.parentNode.childNodes[x]);
				
				if(after) {
					
					// only objects 
					if(tmpRef.getH() > 0) {
						// check if element blocks
						if(prevOP < tmpRef.getOP()) {
							
							tmpHeight = tmpHeight + parseInt(tmpRef.getH());
						}
					
					}
					
				}
				
				// only find height if not objRef
				if(this.obj.parentNode.childNodes[x] == this.obj) {
					
					// setting tmpHeight = offset height
					prevOP 		= this.getOP();
					
					tmpHeight	= prevOP + this.getDH();
					after 		= 1;
				}
			}
			
			// getting parent
			var objParent = mainElm.get(this.obj.parentNode);
			
			// if body use browser height
			if(objParent.obj.nodeName == "BODY") {
				// set height body height - tmpHeight
				var newHeight = browser.height() - tmpHeight;
				var newInnerHeight = this.getFIH();
				
				// checkmodulearea if visible;
				var tmpModCont = mainElm.get('moduleEditorContainer');
				
				if(tmpModCont.obj) {
				
					var modHeight = tmpModCont.getY() + tmpModCont.getH() - tmpHeight;
					newHeight = modHeight>newHeight?modHeight:newHeight;
				}
				
				if(newInnerHeight < newHeight) {
					
					this.setH(newHeight + "px");
				} else {
					this.setH(newInnerHeight + "px");
				}
				
				
			} else {
				// set height - tmpHeight
				var newHeight = objParent.getH() - tmpHeight;
				
				this.setH(newHeight + "px");
				
				
			}
			
			// attaching event to resize
			mainEvt.attachOnResize("setFH()",this);
			
		}
		
		
		// function for getting full inner height;
		this.getFIH = function () {
			
			var	prevOP		= 0;
			var maxHeight	= 0;
			var tmpHeight	= 0;
			var	after		= 0;
			
			// we need to find all nodes in same level after the element and find their height
			for(var x = 0; x < this.obj.childNodes.length; x++) {
				
				
				var tmpRef = mainElm.get(this.obj.childNodes[x]);
				
				if(tmpRef.fh) {
					
					tmpRef.obj.style.height = "auto"
				} 
				
				tmpHeight = tmpRef.getH();
				
				if(tmpHeight > 0) {
						
					maxHeight = (tmpHeight > maxHeight)?tmpHeight:maxHeight;
						
				}
				
				
			}
			
			return maxHeight - 2 ;
			
			
		}
		
		// function for setting full inner height;
		this.setFIH = function () {
			
			var	prevOP		= 0;
			var maxHeight	= 0;
			var tmpHeight	= 0;
			var	after		= 0;
			
			
			
			// we need to find all nodes in same level after the element and find their height
			for(var x = 0; x < this.obj.childNodes.length; x++) {
				
				
				var tmpRef = mainElm.get(this.obj.childNodes[x]);
				
				if(!tmpRef.fh) {
					
					tmpHeight = tmpRef.getH();
					
					if(tmpHeight > 0) {
						
						maxHeight = (tmpHeight > maxHeight)?tmpHeight:maxHeight;
						
					}
					
					
				} else {
					
					
					tmpHeight =  tmpRef.getFIH();
					
					if(tmpHeight > 0) {
						
						
						maxHeight = (tmpHeight > maxHeight)?tmpHeight:maxHeight;
						
					}
					
				}
			}
			
			if(this.getH() < maxHeight) {
				
				this.setH(maxHeight + "px");
				
			}
			
			// attaching event to resize
			mainEvt.attachOnResize("setFIH()",this);
			
		}
	}
	
	return this;
}