/* Planavsky.com - TJavascript Library */
/* ********************************************************************* */
/* Objects:
	- oBrowserWindow : describes browser type properties and dimensions 
	- oHtmlElement : adds interaction to HTML elements 
	- oMvblListEl :
	- oContainer :
	- oMouse : describes and sets mouse event properties
   
   Bugs/Notes:
   - Need to figure out a function to not allow selection of text within 
     elements that are being moved
   - Need to add z-index function for html element being moved
   - How can you call back objects in the tj namespace similar to how it
     is done in Tool Man's core.js? Can you create new instances of 
	 objects?
   - delete DOM Data Display hooks, or create a JS UI for them
   - first item that is dragged starts up in the left hand corner of the screen
*/
/* ********************************************************************* */

// tj namespace 
var tj = {

	get : function(id){
		return document.getElementById(id);
	}
	
}

tj.oBrowserWindow = {
	
	name : null,
	isIE : false,
    isNS : false,
    version : null,
    viewportwidth : null,
	viewportheight : null,
	scrollheight : null,
		  
	construct : function(){
		this.setViewport();
		this.setBrowserData();
	},
	
	setName : function(name){
		this.name = name;
	},
	
	getName : function(){
		alert(this.name);
		return this.name;
	},
	
	setViewport : function(){
		// the more standards compliant browsers (mozilla/netscape/opera/IE7) use window.innerWidth and window.innerHeight
		if (typeof window.innerWidth != 'undefined')
		{
		  this.viewportwidth = window.innerWidth;
		  this.viewportheight = window.innerHeight;
		  this.scrollheight = document.getElementsByTagName('html')[0].offsetHeight;
		}
		// IE6 in standards compliant mode (i.e. with a valid doctype as the first line in the document)
		else if (typeof document.documentElement != 'undefined'
		 && typeof document.documentElement.clientWidth !=
		 'undefined' && document.documentElement.clientWidth != 0)
		{
		   this.viewportwidth = document.documentElement.clientWidth;
		   this.viewportheight = document.documentElement.clientHeight;
		   this.scrollheight = document.getElementsByTagName('body')[0].offsetHeight;
		}
		// older versions of IE
		else
		{
		   this.viewportwidth = document.getElementsByTagName('body')[0].clientWidth;
		   this.viewportheight = document.getElementsByTagName('body')[0].clientHeight;
		   this.scrollheight = document.getElementsByTagName('body')[0].offsetHeight;
		} 
	},
	
	getViewport : function(varname){
		var portvar = eval('this.' + varname);
		alert(portvar);
		return portvar;
	},
	
	setBrowserData : function(){
		  var ua, s, i;
		
		  ua = navigator.userAgent;
			
		  s = "MSIE";
		  if ((i = ua.indexOf(s)) >= 0) {
			this.isIE = true;
			this.version = parseFloat(ua.substr(i + s.length));
			return;
		  }
		
		  s = "Netscape6/";
		  if ((i = ua.indexOf(s)) >= 0) {
			this.isNS = true;
			this.version = parseFloat(ua.substr(i + s.length));
			return;
		  }
		
		  // Treat any other "Gecko" browser as NS 6.1.
		
		  s = "Gecko";
		  if ((i = ua.indexOf(s)) >= 0) {
			this.isNS = true;
			this.version = 6.1;
			return;
		  }
	},
	
	getBrowserType : function(){
		this.setBrowserData();
		if (this.isIE == true){
			return "IE";
		}else{
			return "NS";
		}
	},
	
	getBrowserVersion : function(){
		return this.version;
	}
	
}

tj.oMvblListEl = {
	
	eleId : null,
	containerid : null,
	prevSibling : null,
	nextSibling : null,
	arrCoords : new Array(),
	
	construct : function(event,objid,containerid){
		tj.oContainer.construct(containerid);
		tj.oHtmlElement.construct(event,objid,"move");
		this.eleId = objid;
		this.containerid = containerid;
		this.setPrevSibling(objid);
		this.setNextSibling(objid);
		if (tj.oBrowserWindow.getBrowserType() == "IE") {
			document.attachEvent("onmousemove", tj.oMvblListEl.compareOffsets);
			document.attachEvent("onmouseup", tj.oMvblListEl.resetList);
		}else{
			document.addEventListener("mousemove", this.compareOffsets, true);
			document.addEventListener("mouseup", this.resetList, true);
		}
		this.setEleCoords();
	},
	
	resetList : function(event){
	
	},
	
	compareOffsets : function(event){
		var top = tj.oHtmlElement.getOffsetTop();
		var left = tj.oHtmlElement.getOffsetLeft();
		var right = left + tj.oHtmlElement.offsetWidth;
		var bottom = top + tj.oHtmlElement.offsetBottom;
		if (tj.get('tjhelper')){
			tj.get('otop').value = top;	
			tj.get('oleft').value = left;
		}
		
		var youngerSib = true;
		for (i=0;i<tj.oMvblListEl.arrCoords.length;i++){
			var list = tj.oMvblListEl.arrCoords[i];
			var splitList = list.split(",");
			var sibid = splitList[0];
			var sibtop = splitList[1];
			var sibleft = splitList[2];
			var sibright = Number(sibleft) + Number(tj.get(sibid).offsetWidth);
			var sibbottom = Number(sibtop) + Number(tj.get(sibid).offsetHeight);
			
			if (i == 0){
				var previd = 'NULL';
			}else{
				var prevSibList = tj.oMvblListEl.arrCoords[i - 1];
				var splitPrevList = prevSibList.split(",");
				var previd = splitPrevList[0];
				var previd = splitPrevList[0];
				var prevtop = splitPrevList[1];
				var prevleft = splitPrevList[2];
				var prevright = Number(prevleft) + Number(tj.get(previd).offsetWidth);
				var prevbottom = Number(prevtop) + Number(tj.get(previd).offsetHeight);
			}
			if (i == parseInt(tj.oMvblListEl.arrCoords.length) - 1){
				var nextid = 'NULL';
			}else{
				var nextSibList = tj.oMvblListEl.arrCoords[i + 1];
				var splitNextList = nextSibList.split(",");
				var nextid = splitNextList[0];
				var nexttop = splitNextList[1];
				var nextleft = splitNextList[2];
				var nextright = Number(nextleft) + Number(tj.get(nextid).offsetWidth);
				var nextbottom = Number(nexttop) + Number(tj.get(nextid).offsetHeight);
			} 
			
			if (tj.oMvblListEl.eleId == sibid){
				youngerSib = false;
			}
			
			if (tj.oMvblListEl.eleId != sibid){
				//tj.get('writer').innerHTML = '<br />ID:  ' + sibid + '  PREVIOUS=' + previd + '  NEXT=' + nextid + tj.get('writer').innerHTML;
				if (youngerSib == true){
					//tj.get('writer').innerHTML = '<br />  CHECK' + sibid + tj.get('writer').innerHTML;
					if (left < sibright){
						//tj.get('writer').innerHTML = '<br />ID:  ' + sibid + '   ' + left + ' < ' + sibright + tj.get('writer').innerHTML;
						tj.get(sibid).style.top = nexttop - sibtop + 'px';
						tj.get(sibid).style.left = nextleft - sibleft + 'px';
						//tj.oMvblListEl.createPlaceholder(sibtop,sibleft);
					}
				}else{
					if (right > sibleft){
						tj.get(sibid).style.top = prevtop - sibtop + 'px';
						tj.get(sibid).style.left = prevleft - sibleft + 'px';
					}
				}
			}
		}
	},
	
	createPlaceholder : function(top,left){
		if (!tj.get('tjDragPlaceholder')){
			var phDiv = document.createElement('div');
			phDiv.id = 'tjDragPlaceholder';
			phDiv.setAttribute('style','position:absolute; background:#ddd; width:100px; height:20px; top:' + top + 'px; left:' + left + 'px;');
			tj.get('container1').appendChild(phDiv);
		}else{
			tj.get('tjDragPlaceholder').setAttribute('style','position:absolute; background:#ddd; width:100px; height:20px; top:' + top + 'px; left:' + left + 'px;');
		}
	},
	
	setPrevSibling : function(objid){
		var list = tj.oContainer.getContainerList();
		var splitList = list.split(",");
		for (i=0;i<splitList.length;i++){
			if (objid == splitList[i]){
				this.prevSibling = splitList[i - 1];
			}
		}
	},
	
	setNextSibling : function(objid){
		var list = tj.oContainer.getContainerList();
		var splitList = list.split(",");
		for (i=0;i<splitList.length;i++){
			if (objid == splitList[i]){
				this.prevSibling = splitList[i + 1];
			}
		}
	},
	
	setEleCoords : function(){
		var list = tj.oContainer.getContainerList();
		var splitList = list.split(",");
		for (i=0;i<splitList.length;i++){
			var offTop = tj.get(splitList[i]).offsetTop;
			var offLeft = tj.get(splitList[i]).offsetLeft;
			//create an array here to compare against the moving element's offsets
			if (splitList[i] != 'tjDragPlaceholder'){
				this.arrCoords[i] = splitList[i] + ',' + offTop + ',' + offLeft;
				if (tj.get('tjhelper')){
					tj.get('writer').innerHTML = '<br />Element ' + splitList[i] + ': offTop= ' + offTop + 'offLeft= ' + offLeft + tj.get('writer').innerHTML;
				}
			}
		}
	}
	
}

tj.oContainer = {
	
	list : null,
	
	construct : function(containerid){
		this.setContainerList(containerid);
	},
	
	setContainerList : function(containerid){
		var containerlist = '';
		for (i=0;i<tj.get(containerid).childNodes.length;i++){
			if(tj.get(containerid).childNodes.item(i).id){
				//alert(tj.get(containerid).childNodes.item(i).id);
				var containerlist = containerlist + tj.get(containerid).childNodes.item(i).id;
				if (i != tj.get(containerid).childNodes.length){
					containerlist = containerlist + ',';
				}
			}
		}
		containerlist = containerlist.slice(0, -1)
		//alert(containerlist);
		this.list = containerlist;
	},
	
	getContainerList : function(){
		return this.list;
	}
	
}

tj.oHtmlElement = {

	htmlObj : null,
	screenTop : 0,
	screenLeft : 0,
	eleTop : 0,
	eleLeft : 0,
	offsetTop: 0,
	offsetLeft : 0,
	browserType : tj.oBrowserWindow.getBrowserType(),
	height : null,
	width : null,
	
	construct : function(event,objid,action){
		this.htmlObj = tj.get(objid);
		this.setHeight(objid);
		this.setWidth(objid);
		this.screenTop = 0;
		this.screenLeft = 0;
		this.eleTop = 0;
		this.eleLeft = 0;
		
		if (action){
			if (action == 'move'){
				tj.get(objid).style.position = 'relative';
				tj.get(objid).style.cursor = 'move';
				this.startMove(event,objid);
			}
		}
	},
	
	setEleTop : function(top){
		if (top != ''){
			this.eleTop = parseInt(top, 10);
		}
	},
	
	getEleTop : function(){
		return this.eleTop;
	},
	
	setEleLeft : function(left){
		if (left != ''){
			this.eleLeft = parseInt(left, 10);
		}
	},
	
	getEleLeft : function(){
		return this.eleLeft;
	},
	
	setHeight : function(objid){
		this.height = tj.get(objid).offsetHeight;
	},
	
	setWidth : function(objid){
		this.width = tj.get(objid).offsetWidth;
	},
	
	getScreenLeft : function(objid){
		/* if calling this function when the html object 
		   is not created yet, construct the object */
		if (objid){
			this.construct(objid);
		}
		return this.screenLeft;
	},
	
	getScreenTop : function(objid){
		if (objid){
			this.construct(objid);
		}
		return this.screenTop;
	},
	
	getOffsetTop : function(){
		return this.htmlObj.offsetTop;
	},
	
	getOffsetLeft : function(){
		return this.htmlObj.offsetLeft;
	},
	
	move : function(){
		if (tj.oHtmlElement.browserType == "IE"){
			tj.oMouse.setPosition();
		}else{
			document.addEventListener("mousemove", tj.oMouse.setPosition, true);
		}
		if (tj.get('tjhelper')){
			tj.get('x').value = tj.oMouse.getX();
			tj.get('y').value = tj.oMouse.getY();
		}
		var x = tj.oMouse.getX();
		var y = tj.oMouse.getY();
		
		if (tj.oHtmlElement.htmlObj.style.top == ''){
			tj.oHtmlElement.htmlObj.style.top = '0px';
			tj.oHtmlElement.htmlObj.style.left = '0px';
		}
		tj.oHtmlElement.htmlObj.style.top = (tj.oHtmlElement.eleTop + y - tj.oMouse.getStartY()) + 'px';
		tj.oHtmlElement.htmlObj.style.left = (tj.oHtmlElement.eleLeft + x - tj.oMouse.getStartX()) + 'px'; 
	},
	
	stopMove : function(){
		  if (tj.oHtmlElement.browserType == "IE"){
			document.detachEvent("onmousemove", tj.oHtmlElement.move);
			document.detachEvent("onmouseup", tj.oHtmlElement.stopMove);
		  }else{
			document.removeEventListener("mousemove", tj.oHtmlElement.move, true);
			document.removeEventListener("mouseup", tj.oHtmlElement.stopMove, true);
		  }
	},
	
	startMove : function(event,objid){
		tj.oMouse.findClickPosition(event);

		var element = tj.get(objid);
		this.setEleTop(element.style.top);
		this.setEleLeft(element.style.left);
		if (tj.get('tjhelper')){
			tj.get('top').value = this.getEleTop();
			tj.get('left').value = this.getEleLeft();
		}
		if (this.browserType == "IE"){
			document.attachEvent("onmousemove", this.move);
			document.attachEvent("onmouseup", this.stopMove);
			window.event.cancelBubble = true;
			window.event.returnValue = false;
		}else{
			document.addEventListener("mousemove", this.move, true);
			document.addEventListener("mouseup", this.stopMove, true);
			//event.preventDefault();
		}
	}
	
}

tj.oMouse = {
	
	mousex : null,
	mousey : null,
	startx : null,
	starty : null,
	browserType : tj.oBrowserWindow.getBrowserType(),
		
	setPosition : function(event){
		  if (this.browserType == "IE") {
			this.mousex = window.event.clientX + document.documentElement.scrollLeft
			  + document.body.scrollLeft;
			this.mousey = window.event.clientY + document.documentElement.scrollTop
			  + document.body.scrollTop;
		  }else{
			tj.oMouse.mousex = event.clientX + window.scrollX;
			tj.oMouse.mousey = event.clientY + window.scrollY;
		  }
	},
	
	findClickPosition : function(e){
		  if (tj.oBrowserWindow.getBrowserType() == "IE") {
			tj.oMouse.startx = window.event.clientX + document.documentElement.scrollLeft
			  + document.body.scrollLeft;
			tj.oMouse.starty = window.event.clientY + document.documentElement.scrollTop
			  + document.body.scrollTop;
		  }else{
			tj.oMouse.startx = e.clientX + window.scrollX;
			tj.oMouse.starty = e.clientY + window.scrollY;
		  }
		  if (tj.get('tjhelper')){
		  	tj.get('startx').value = tj.oMouse.getStartX();
		  	tj.get('starty').value = tj.oMouse.getStartY(); 
		  }
	},
	
	getX : function(){
		return this.mousex;
	},
	
	getY : function(){
		return this.mousey;
	},
	
	getStartX : function(){
		return this.startx;
	},
	
	getStartY : function(){
		return this.starty;
	}
	
}

tj.oHelper = {

	draggerData : function(){
		document.write('<table border="1"><tr><th colspan="2">DOM Data Display</th></tr><tr><td rowspan="9"><div id="writer" style="width:300px; height:200px; overflow:auto; border:1px solid #000;"></div></td><td>Mouse X Coord: <input type="text" name="x" id="x" value="" /></td></tr><tr><td>Mouse Y Coord: <input type="text" name="y" id="y" value="" /></td></tr><tr><td>Mouse Start X Coord: <input type="text" name="startx" id="startx" value="" /></td></tr><tr><td>Mouse Start Y Coord: <input type="text" name="starty" id="starty" value="" /></td></tr><tr><td>Drag Element Top: <input type="text" name="top" id="top" value="" /></td></tr><tr><td>Drag Element Left: <input type="text" name="left" id="left" value="" /></td></tr><tr><td>Drag Element Offset Top: <input type="text" name="otop" id="otop" value="" /></td></tr><tr><td>Drag Element Offset Left: <input type="text" name="oleft" id="oleft" value="" /></td></tr><tr><td>Misc: <input type="text" name="misc" id="misc" value="" /><input type="hidden" name="tjhelper" id="tjhelper" value="" /></td></tr></table>');
	}
	
}

/* EXAMPLES -------------------------------------------------------
	Move an element: onmousedown="tj.oHtmlElement.construct(event,'htmlElement3','move');"
*/
