document.dyn = new Array();
var dynLoaded = true;
var is = "", topZ = 500;

// Browser check
// --------------------------------------------------------
function BrowserCheck() {
	var n = navigator; var d = document;
	var v = n.appVersion;
	var ua = n.userAgent;

	this.IE = (ua.indexOf('MSIE') > -1)
	this.NS = (n.appName.indexOf('Netscape') > -1)
	this.OP = (ua.indexOf('Opera') > -1)

	this.IE4 = (d.all && !d.getElementById)? true:false;
	this.IE4UP = (this.IE &&(d.all || d.getElementById))? true:false;
	this.IE5 = (ua.indexOf('MSIE 5.0') > -1)
	this.IE55 = (ua.indexOf('MSIE 5.5') > -1)
	this.IE6 = (ua.indexOf('MSIE 6.0') > -1)
	this.NS4 = (this.NS && v.indexOf("4.") > -1)? true:false;
	this.NS6 = (this.NS && d.getElementById)? true:false;
	this.DOM = (d.getElementById && d.createElement)? true:false;
	this.OP5 = (this.OP && ua.indexOf('5.') > -1)
	this.MAC = (n.platform.indexOf('Mac') > -1)
}	is = new BrowserCheck();

// Layer object
// --------------------------------------------------------
function dynObject(id, nestIn, attach) {
	this.id = id;
	this.nested = nestIn || false;
	this.parent = false;
	this.children = [];
	this.attached = attach;

	this.create();
}
	dynProto = dynObject.prototype;	
	function attachObject(id, nestIn) {
		return document.dyn[id] || new dynObject(id, nestIn, true);
	}


// Basic Functions
// --------------------------------
dynProto.moveTo = function(x, y) {
	this.x = x; this.y = y;

	if(this.limitedMove) {
		var mLim = this.limits
		if(x < mLim[0]) this.x = mLim[0];
		if(y < mLim[1]) this.y = mLim[1];
		var xl = mLim[2] - this.w; if(x > xl) this.x = xl;
		var yl = mLim[3] - this.h; if(y > yl) this.y = yl;
	}

	if(!this.mayNotMove) {
		this.css.left = this.x;
		this.css.top  = this.y;
	}
}

dynProto.slideTo = function(x, y, time, style) {
	if(time < 50) {
		alert('Warning: slide-time too short (<50)');
		return;
	}
	this.tx = x; this.ty = y;
	this.stepX = (this.tx - this.x)/(time/50);
	this.stepY = (this.ty - this.y)/(time/50);
	this.slideStyle = (style == "slowed")? 0.97:false;
	if(this.timer) clearInterval(this.timer);
	this.timer = setInterval('document.dyn["'+this.id+'"].slideStep()', 50);
	this.isSliding = true;
}

dynProto.slideBy = function(dx, dy, time, style) {
	this.slideTo(this.x+dx, this.y+dy, time, style);
}

dynProto.slideStep = function() {
	if((this.tx - this.x)/this.stepX < 1 
	 || (this.ty - this.y)/this.stepY < 1) {
		clearInterval(this.timer);
		if(this.onSlideEnd) eval(this.onSlideEnd);
		this.moveTo(this.tx, this.ty);
		this.isSliding = false;
	} else
		this.moveBy(this.stepX, this.stepY);
	if(this.slideStyle) {
		this.stepX *= this.slideStyle;
		this.stepY *= this.slideStyle;
	}
}

dynProto.moveBy = function(dx, dy) {
	this.moveTo(this.x + dx, this.y + dy);
}

dynProto.write = function(content) {
	this.html = content;
	if(is.NS4) { with(this.document) 
		{open(); write(content); close();}
	} else { this.innerHTML = '\n'+ this.html +'\n';}
}

dynProto.add = function(content) {
	this.html += content;
	this.write(this.html);
}

dynProto.setVisible = function(mode) {
	this.css.visibility = (mode)? (this.nested? 'inherit':'visible'):"hidden";
	this.visible = mode;
}

dynProto.setZIndex = function(z) {
	this.css.zIndex = this.z = z;
	if(z > topZ) topZ = z;
}

dynProto.bringToFront = function() {
	this.setZIndex(topZ + 1);
}

dynProto.setBackground = function(to) {
	if(to.indexOf('.') != -1) {
		if(is.IE4UP || is.NS6) this.css.backgroundImage = "url("+to+")";
		else { if(is.NS4) this.background.src = to; }
	} else {
		if(is.OP5) this.css.background = to;
		else if(is.IE4UP || is.NS6) this.css.backgroundColor = to;
		else { if(is.NS4) this.bgColor = to; }
	}
}

dynProto.resizeTo = function(w,h) {
	if(is.NS4 && w && h) this.resizeTo(w,h);
	if(w) this.setWidth(w);
	if(h) this.setHeight(h);
}

dynProto.setWidth = function(w) {
	this.w = w; this.r = this.x + w;
	if(is.OP5) this.css.pixelWidth = w;
	else this.resize.width = w;
}

dynProto.setHeight = function(h) {
	this.h = h; this.b = this.y + h;
	if(is.OP5) this.css.pixelHeight = h;
	else this.resize.height = h;
}

dynProto.clipTo = function(t,w,h,l) {
	this.clip = [t,w,h,l];
	if(is.IE4UP || is.NS6) {
		this.css.clip = 'rect('+t+','+w+','+h+','+l+')';
	} else if(is.NS4) {
		with(this) {
			clip.top = t;
			clip.width = w;
			clip.height = h;
			clip.left = l;
		}
	}
}

dynProto.getDimensions = function() {
	if(is.IE4UP || is.NS6) {
		this.w = (is.IE4UP)? this.clientWidth:this.offsetWidth;
		this.h = (is.IE4UP)? this.clientHeight:this.offsetHeight;
	} else if(is.NS4) {
		this.w = this.document.width;
		this.h = this.document.height;
	}
	this.x = parseInt(this.css.left); this.r = this.x + this.w;
	this.y = parseInt(this.css.top);  this.b = this.y + this.h;		
}

dynProto.setProperties = function(x, y, w, h, vis, bg, z) {
	this.moveTo(x,y); 
	this.resizeTo(w,h);
	if(vis) this.setVisible((vis=="visible")?true:false);
	if(bg) this.setBackground(bg);
	if(z) this.setZIndex(z);
}

dynProto.limitMovement = function(x,y,w,h) {
	this.limits = [x,y,w,h];
	this.limitedMove = true;
}

dynProto.createImage = function(src, name, w, h) {
	var imgName = (name)? (' name="'+name+'"'):'';
	var iDim = (w? (' width='+w+' '):'') + (h? (' height='+h+' '):'');
	this.write('<img'+imgName+' src="'+src+'" '+iDim+' border=0 align="top">');
	if(name) {
		var target = (is.NS4)? this.document:document;
		this.image = target.images[name];
	}
}

dynProto.setOpacity = function(to) {
	this.opacity = to;
	if(is.NS6) this.css.MozOpacity = to/100;
	if(is.IE4UP) this.css.filter = 'alpha(opacity='+to+')'
}

dynProto.setBorder = function(width, style, color) {
	this.css.borderWidth = width;
	this.css.borderStyle = style || 'solid';
	this.css.borderColor = color || 'black';
}

var defaultAttributes = 'position:absolute; left:0px; top:0px; visibility:hidden;';

dynProto.create = function() {
	if(this.nested && !this.attached) {
		this.parent = attachObject(this.nested)
		this.parent.children[this.parent.children.length] = this;
		this.parent.children[this.id] = this;
	}

	// Initialise new Object
	// --------------------------------
	if(!this.attached) {
		if(is.IE4UP) {
			var source = '<DIV ID="'+this.id+'" STYLE="'+defaultAttributes+'"></DIV>';
			var target = (this.nested)? getObject(this.nested):document.body;
			target.insertAdjacentHTML('beforeEnd',source);
		} else if(is.DOM) {
			var source = document.createElement("Div");
			source.setAttribute('style', defaultAttributes); source.id = this.id;
			var target = (this.nested)? getObject(this.nested):document.body;
			target.appendChild(source);
		} else if(is.NS4) {
			if(!this.parent) document.layers[this.id] = new Layer(100);
			else document.layers[this.id] = new Layer(100, getObject(this.nested));
		}
	}

	this.layer = getObject(this.id);
	if(!this.layer) { alert('WARNING \n\n Layer: '+this.id+' was NOT found');}
	if(is.NS4) {
		this.layer.id = this.id;
		this.layer.style = this.layer;
	}

	this.css = this.layer.style;
	this.resize = (is.NS4)? this.layer.document:this.css;

	document.dyn[document.dyn.length] = this;
	document.dyn[this.id] = this;
	if(this.attached) this.getDimensions();
}

// Finding objects
// --------------------------------------------------------
function getObject(id) {
	if(is.IE4UP) return document.all[id];
	if(is.NS6) return document.getElementById(id);
	if(is.NS4) return findObject(id, document);
}
	function findObject(name, doc) {
		if(doc.layers[name]) return doc.layers[name];
		for (var i=0; i<doc.layers.length; i++) {
			var res = findObject(name, doc.layers[i].document);
			if(res) return res;
			else continue;
		}	return false;
	}

// Document properties
function documentProperties() {
	this.xScroll = getXscroll;
	this.yScroll = getYscroll;

	this.screenWidth  = screen.width;
	this.screenHeight = screen.height;
	this.availWidth = (is.IE)? document.body.clientWidth:window.innerWidth;
	this.availHeight  = (is.IE)? document.body.clientHeight:window.innerHeight;

	function getXscroll() {
		return (is.IE)? document.body.scrollLeft:window.pageXOffset;
	}

	function getYscroll() {
		return (is.IE)? document.body.scrollTop:window.pageYOffset;		
	}
}

// Reading obj properties
// --------------------------------------------------------
function getProperties(obj) {
	var res = "";
	for(var i in obj) {
		res += i +' \t-  ';
		if(typeof obj[i] == 'function') { 
			res += '[function]';
		} else {
			res += obj[i];
		}	res += '\n';
	}	alert(res);
}

// document mouse events
// --------------------------------------------------------
var mouseX = 0;
var mouseY = 0;

var dynMoves = new Array();
var dynDowns = new Array();
var dynUps = new Array();
var dynLoads = new Array();
var dynResizes = new Array();

var dynDragging = false;
var doc = null;
var dynLoaded = false;

if(is.NS4) { document.captureEvents(Event.MOUSEMOVE||Event.MOUSEDOWN||Event.MOUSEUP); }
document.onmousemove = dynMouseMove;
document.onmousedown = dynMouseDown;
document.onmouseup = dynMouseUp;
document.attachEvent = attachDocumentEvent;

window.onload = dynOnload;
window.onresize = dynOnresize;

function attachDocumentEvent(type, func) {
	switch(type.toLowerCase()) {
		case "onmousemove": dynMoves[dynMoves.length] = func; break;
		case "onmousedown": dynDowns[dynDowns.length] = func; break;
		case "onmouseup": dynUps[dynUps.length] = func; break;
		case "onload": dynLoads[dynLoads.length] = func; break;
		case "onresize": dynResizes[dynResizes.length] = func; break;
		default: return; break;
	}
}

function dynMouseMove(e) {
	mouseX = (is.IE)? (event.x + document.body.scrollLeft):e.pageX;
	mouseY = (is.IE)? (event.y + document.body.scrollTop):e.pageY;
	execute(dynMoves);	
	if(dynDragging) return false;
}

function dynMouseDown(e) {
	mouseButton = (is.IE)? event.button:e.which;
	execute(dynDowns);	
}

function dynMouseUp(e) {
	execute(dynUps);
}

function dynOnresize() {
	doc = new documentProperties();
	execute(dynResizes);
}

function dynOnload() {
	doc = new documentProperties();
	dynLoaded = true;
	if(typeof init == 'function') init();
	execute(dynLoads);
}


// layer mouse events
// --------------------------------------------------------
var activeObj = null;

dynProto.attachEvent = function(type, func) {
	if(!this.hasEvents) {
		this.hasEvents = true;

		this.mOvers = new Array(); this.mOuts = new Array();
		this.mDowns = new Array(); this.mUps = new Array();

		var target = (is.NS4)? this.layer.document:this.layer;
		this.layer.onmouseover = dynLayerMouseOver;
		this.layer.onmouseout = dynLayerMouseOut;
		this.layer.tag = this.id;
		target.onmousedown = dynLayerMouseDown;
		target.onmouseup = dynLayerMouseUp;
	}

	switch(type.toLowerCase()) {
		case "onmouseover": this.mOvers[this.mOvers.length] = func; break;
		case "onmouseout":  this.mOuts[this.mOuts.length] = func; break;
		case "onmousedown": this.mDowns[this.mDowns.length] = func; break;
		case "onmouseup":   this.mUps[this.mUps.length] = func; break;
		default: return; break;
	}
}

dynProto.removeEvents = function() {
	this.mOvers = this.mOuts = this.mDowns = this.mUps = [];
}

function dynLayerMouseOver() {
	activeObj = document.dyn[this.tag];
	execute(activeObj.mOvers);
}

function dynLayerMouseOut() {
	if(!activeObj) return;
	execute(activeObj.mOuts);
	activeObj = null;
}

function dynLayerMouseDown(e) {
	if(!activeObj) return;
	activeObj.clickX = (is.NS)? e.layerX : event.offsetX;
	activeObj.clickY = (is.NS)? e.layerY : event.offsetY;
	execute(activeObj.mDowns);
}

function dynLayerMouseUp() {
	if(!activeObj) return;
	execute(activeObj.mUps);	
}

// Event array Execute
// --------------------------------------------------------
function execute(arrayObj) {
	for(var i=0; i<arrayObj.length; i++) {
		eval(arrayObj[i]);
	}
}

// beeHive - Drag & drop plugin
// --------------------------------------------------------

var dragObj = false;
var docHasEvents = false;

dynProto.enableDragDrop = function(dragProperties) {
	if(!docHasEvents) {
		docHasEvents = true;
		document.attachEvent("onmousemove", "dynHandleDrag()");
		document.attachEvent("onmouseup", "dynStopDrag()");
	}

	function argContains(str) {
		if(!dragProperties) return false;
		return (dragProperties.indexOf(str) > -1)? true:false;
	}

	this.isDraggable = true;
	this.dragParent = argContains('dragParent');
	this.dragHorz = argContains('horizontal');
	this.dragVert = argContains('vertical');
	this.toFront = argContains('bringToFront');

	if(argContains('limit')) {
		var args = new RegExp(/\((\-?\d+\,){3}\d+\)/).exec(dragProperties)
		if(!args) alert('illegal draglimit expression')
		var target = (this.dragParent)? this.parent:this
		eval('target.limitMovement' + args[0]);		
	}

	if(this.dragParent) {
		this.parent.dragHorz = this.dragHorz;
		this.parent.dragVert = this.dragVert;
	}

	this.xAnch = 0;	this.yAnch = 0;
	this.attachEvent("onmousedown", "dynStartDrag()");
	this.attachEvent("onmouseup", "dynStopDrag()");	
}

dynProto.setDragAction = function(functionName) {
	this.dragAction = functionName;
}

function dynStartDrag(){
	dragObj = activeObj.dragParent? activeObj.parent:activeObj;
	dragObj.xAnch = mouseX - dragObj.x;
	dragObj.yAnch = mouseY - dragObj.y;
	if(activeObj.toFront) dragObj.bringToFront()
	dynDragging = true;	
}

function dynStopDrag(){
	dragObj.beingDragged = false;
	if(dragObj.onDragEnd) eval(dragObj.onDragEnd);
	dragObj = false;
	dynDragging = false;
}

function dynHandleDrag(){
	if(dragObj && dynDragging) {
		dragObj.beingDragged = true;
		dragObj.dragToX = dragObj.dragVert? dragObj.x:(mouseX - dragObj.xAnch);
		dragObj.dragToY = dragObj.dragHorz? dragObj.y:(mouseY - dragObj.yAnch);

		if(dragObj.dragAction) {eval(dragObj.dragAction);}
		with(dragObj) {moveTo(dragToX, dragToY);}
	}
}
