
	iClientBase = function(){
		this.instID = 'iClientBase' + parseInt(Math.random()*1000000);
		this.options = new Hash();
		if (this.is_ie()){
			// grrrr! HATE these hacks
			this.contentPadding = 0;
		}else{
			this.contentPadding = 20;
		}
		this.navWidth = 125;// + this.contentPadding;
		// set some internal states
		this.isLoading = false;
		this.isAnimating = false;
	}	
	
	iClientBase = iClientBase.extendsFrom(wps.base);


	iClientBase.prototype.objInit = function(){
		this.productID = this.getProductProperty(this.node, 'product_id');
		if (this.debug) wps.debug.log(this.instID + ' ('  + this.productID + ') initializing');
		this.openedWidth =  this.getProductProperty(this.node, 'width');
		this.options.set('productName', this.getProductProperty(this.node, 'name'));
		this.options.set('bgColor', this.getProductProperty(this.node, 'BGColor'));
		this.options.set('fgColor',  this.getProductProperty(this.node, 'FGColor'));
	}


	iClientBase.prototype.setChildren = function(){
		if (this instanceof iClientMainBar){
			var appendTo = Builder.node('div', {className:'children'}); // create container into which all children will be parsed
			this.output.appendChild(appendTo);
		}else{
			var appendTo = this.output;	
		}
		$A(this.node.childNodes).each(
			(function(productNode){
				if (productNode.nodeName == 'product'){
					var productID = this.getProductProperty(productNode, 'product_id');
					var newObj = new iClientPage(productNode, this);
					if (this.debug)	wps.debug.log(this.instID + " :: Added child " + newObj.instID + " (" + productID +")");
						
					// do NOT init obj. yet, only when opened
					this.children.set(productID, newObj);
					// create a container for the child
					var childContainer = Builder.node('div', {className:'childContainer',id:newObj.instID});
					this.childContainers.set(productID, childContainer);
					appendTo.appendChild(childContainer);
				}
			}).bind(this)
		)
	}

	iClientBase.prototype.getChildObjects = function(productID, func){
		var wpsRPC = new wps.rpc;
		wpsRPC.debug = true;
		wpsRPC.attachWaiter(this.waiter, this);
		wpsRPC.attachUnWaiter(this.unWaiter, this);
		wpsRPC.createCall('ivoClient', func, this);
		wpsRPC.call('getChildObjects', 'parentObjectID=' + productID);
	}
	
	iClientBase.prototype.show = function(elem, options){
		this._show(elem, options);
	}

	iClientBase.prototype._show = function(elem, options){
		if (!elem) var elem = this.output;
		if (!options) var options = {duration:'0.3'};
		//if (elem) new Effect.PhaseIn(elem, options);
		if (this.isLoading || this.isAnimating){
			// prevent container to be shown before the content is loaded
			setTimeout(
				(function(){this._show(elem, options)}).bind(this),
				250
			)
			return;
		}
		if (elem) Element.show(elem);
	}

	iClientBase.prototype.hide = function(elem, options){
		if (!elem) var elem = this.output; 
		if (!options) var options = {duration:'0.3'};
		if (this.children.keys().length > 0){
			this.children.each(
				(function(child){
					if (child.value.isOpen) {
						child.value.hide();
						child.value.isOpen = false;
					}
				}).bind(this)
			)
		}
		if ( (this.children.keys().length > 0)&& ($('childNavigationOf' + this.instID))) Element.hide($('childNavigationOf' + this.instID)); 
		//if (elem) new Effect.PhaseOut(elem, options);
		if (elem) Element.hide(elem);
		//this.pob.setWidth();
		//this.pob.setSize();
	}
	
	iClientBase.prototype.waiter = function(){
		if (this instanceof iClientPage){
			this.mainBar.waiterElem.style.display = "block";
			return;
		}
		this.waiterElem.style.display = "block";
	}
	
	iClientBase.prototype.unWaiter = function(){
		if (this instanceof iClientPage){
			this.mainBar.waiterElem.style.display = "none";
			return;
		}
		this.waiterElem.style.display = "none";
	}	
	
	
	iClientBase.prototype.getProductProperty = function(productNode, propKey){
		var returnValue;
		if (propKey == 'product_id'){
			var ret = $A(productNode.childNodes).findAll(
				(function(aChildNode){
					if (aChildNode.nodeName == 'product_id'){
						returnValue = wps.dom.getElementValue(aChildNode);
						return;
					}
				}).bind(this)
			)
		}else{
			var ret = $A(productNode.childNodes).findAll(
				(function(aChildNode){
					if (aChildNode.nodeName == 'property'){
						if (wps.dom.getNodeValue(aChildNode.getElementsByTagName('key')) == propKey){
							returnValue = wps.dom.getNodeValue(aChildNode.getElementsByTagName('value'));
							return;
						}
						
					}
				}).bind(this)
			)
		}
		return returnValue;
	}
	
	iClientBase.prototype.getChildObjectByName = function(parentNode, key){
		var retArr = new Array();
		$A(parentNode.childNodes).each(
			(function(node){
				if (node.nodeName=='product'){
					// determine name:
					var objectName = this.getProductProperty(node, 'name');
					if (objectName == key) retArr.push(node);
				}
			}).bind(this)
		)
		return retArr;
	}	
	
	iClientBase.prototype.setContent = function(){
		this.isLoading = true;
		this.getContentAtProduct(this.productID, this.setRemoteContent.bind(this))	
	}
	
	iClientBase.prototype.setRemoteContent = function(req){
		var content = req.responseText;
		if (!$(this.instID + '_childContent')){
			if (this.pob instanceof iClientPage){
				// add a closer, only if parent is a iCLientPage
				var closer = Builder.node('div', {className:'childCloser'}, [' < ']);
				this.addEvent(closer, 'click', (function(){this.toggle()}).bind(this))
				this.output.appendChild(closer);
			}
			var div = Builder.node('div', {id:this.instID + '_childContent', className:'childContent', style:'width:' + (this.openedWidth )});
			this.contentContainer = div;
			this.output.appendChild(div);
		}else{
			var div = $(this.instID + '_childContent');
			Element.update(div, '');
		}
		Element.update(div, content);
		this.isLoading = false;
		this.enableZoom();
		this.resizeContent();
	}
	
	iClientBase.prototype.resizeChildren = function(){
		this.children.each(
			function(child){
				if (child.value.isOpen) {
					child.value.resizeContent();
				}	
			}
		)
	}
	
	iClientBase.prototype.resizeContent = function(){
		var screenSize = Element.getDimensions(document.body);
		var contentHeight = parseInt(screenSize.height) - 236;
//		var navHeight = parseInt($('childNavigationOf' + this.instID).childNodes.length) * 21;
//		console.log( navHeight , contentHeight, $(this.instID + '_childContent'), $('childNavigationOf' + this.instID), $('childNavigationOf' + this.instID).getHeight());
		if (this.children.keys().length > 0){
			this.children.each(
				function(child){
					if (child.value.isOpen) {
						child.value.resizeContent();
					}	
				}
			)
		}
		try{
			$(this.instID + '_childContent').setStyle({height:contentHeight-10});
		}catch(e){
		} // DO not handle DOM error's here
	}	
	
	iClientBase.prototype.getContentAtProduct = function(productID, func){
		//if (!func) var func = (function(req){this.setContent(req, container)}).bind(this)
		var wpsRPC = new wps.rpc;
		wpsRPC.debug = true;
		wpsRPC.attachWaiter(this.waiter, this);
		wpsRPC.attachUnWaiter(this.unWaiter, this);
		wpsRPC.createCall('ivoClient', func, this);
		wpsRPC.call('getContent', 'objectID=' + productID);		
	}

	
	iClientBase.prototype.setLeft = function(leftPos){
		var currLeft = parseFloat(Element.getStyle(this.output,'left'));
		if (currLeft != leftPos){
			this.isAnimating = true;
//			if (this.is_ie()){
				new Effect.Move(this.output, {x:leftPos,mode:'absolute', duration:'0.8'});
//			}else{
//				this.addAnimation(this.output, 'Move', {x:leftPos,mode:'absolute', duration:'0.8'});
//			}
			//
			setTimeout( // make object aware of running animations
				(function(){this.isAnimating = false;}).bind(this),
				800
			)	
		}
	}	

	iClientBase.prototype.getChildrenWidth= function(){
		var sumWidth  = 0;
		this.children.each(
			function(child){
				 if (child.value.isOpen) {
				 	sumWidth += parseInt(child.value.getWidth());
					if (this.debug) wps.debug.log('ADDING WIDTH FROM CHILDOBJECT : ' + child.value.productID + "(" + child.value.options.get('productName') + ")");
				 }
			}
		)
		return sumWidth;
	}

	iClientBase.prototype.getWidth = function(){
		var sumWidth = this.getChildrenWidth();
		if (this.hasNavigation) sumWidth = sumWidth + this.navWidth;
		return (parseInt(this.openedWidth) + sumWidth + this.contentPadding);
	}

	iClientBase.prototype.setWidth = function(){
		if (this instanceof iClientMainBar){
			// mainbars have a different way of opening/closing
			var sumWidth = this.getChildrenWidth();
			var isOpen = this.isOpen;
			if (isOpen){
				var amount =  sumWidth;
			}else{
				var amount = parseInt(this.closedWidth);
			}
			this.width = 	amount;
			if (this.debug)	wps.debug.log(this.instID + " :: Setting width to " + amount);
			if (amount != 0){
				this.isAnimating = true;
				new Effect.ReSize(this.output, {amount:0, direction:'horiz', duration:'0.8', toSize:parseInt(amount)});
				setTimeout( // make object aware of running animations
					(function(){this.moveViewport(amount);this.isAnimating = false;}).bind(this),
					800
				)	
				this.pob.setSize();
			}			
		}else{
			if (this.debug)	wps.debug.log(this.instID + " :: Setting width (revert to pob)");
			if (this.pob){
				this.pob.setWidth();
			}else{
				// we're at the top!
			}
		}
	}		
	
	iClientBase.prototype.moveViewport = function(amount){
		var screenSize = Element.getDimensions(document.body);
		var vpWidth = parseInt(screenSize.width) ;

		var currLeft = parseFloat(Element.getStyle(this.output,'left'));		
		var barOuterRight =  (parseInt(currLeft) + parseInt(amount));
		if (vpWidth < barOuterRight){
			barOuterRight = barOuterRight - vpWidth;
			if (this.is_ie()) barOuterRight = barOuterRight+25;
			self.scrollTo(barOuterRight, 0);
		}
	}
	
	iClientBase.prototype.draw = function(){
		if (this.debug)	wps.debug.log(this.instID + " :: Drawing");
		//set Title
		this.setTitle();
		
		// set navigation
		this.setNavigation();		
		
		// set content:
		this.setContent();
		this.unWaiter();
	}
	
	/** 
	* Extra refactoring
	*/
	iClientBase.prototype.createContainer = function(){
		var container = Builder.node('div', {className:'bar'}); // create container
		container.isOpen = false; // set state
		if (this.options.get('fgColor') !='#') container.style.color = this.options.get('fgColor'); // set colors
		if (this.options.get('bgColor') !='#') container.style.backgroundColor = this.options.get('bgColor');
		container.openedWidth = this.options.get('width');
		container.productID = this.productID;
		container.index = this.index;
		return container;
	}
	
	
	iClientBase.prototype.setSize = function(){
		if (this.output){
			var sumWidth = this.output.parentNode.offsetWidth + this.navWidth;
		}else{
			var sumWidth = 0;
		}
		if (this.debug) wps.debug.log(this.instID + "(" + this.productID + ")setting size");
		this.children.each(
			(function(bar){
				bar = bar.value;
				//if (bar.isOpen){
					bar.setLeft(sumWidth);
					sumWidth = sumWidth + parseInt(bar.width);
					//bar.resortChildren();
				//}
			}).bind(this)
		)
		this.runQueue();
	}		
	
	iClientBase.prototype.toggle = function(event, goOpen){
		if (!goOpen) {
			this.isOpen = !this.isOpen;
		}else{
			this.isOpen = goOpen;
		}
		if (!this.isOpen){
			if (this instanceof iClientPage) 	this.hide(); // hide myself if I am a page, but not when i;m a bar.
			this.children.each(
				(function(child){
					if (child.value.isOpen){
						 child.value.hide();
					}
				}).bind(this)
			)
		}
		this.setWidth();
		this.draw();
		this.pob.setSize();
	}	
	
	iClientBase.prototype.addAnimation = function(elem, effect, options){
		var anim = {elem:elem, effect:effect, options:options}
		this.queue.push(anim);
	}
	
	iClientBase.prototype.runQueue = function(){
		var startAt = 0;
		$A(this.queue).each(
			(function(anim){
					startAt += parseFloat(anim.options.duration) * 250;
					var eff = anim.effect;
					var eff = anim.effect; 
					var elem = anim.elem;
					var options = anim.options;
					this.queue.pop(anim);
// Fires an Effect.Appear for each element with a delay of 100 m
					var func = function(){ new Effect[eff + ''](elem, options)}
					setTimeout(func, startAt);
			}).bind(this)
		)
	}
	
	iClientBase.prototype.runAnim = function(anim){
		console.log(anim);
	}
	
	iClientBase.prototype.enableZoom = function(){
		var images = this.output.getElementsByTagName('img');
		$A(images).each(
			(function(img){
				if (img.className != 'zoom') return;
				var largeSrc = img.src.split('/');
				var image = largeSrc.pop();
				var out = '';
				$A(largeSrc).each(
					function(srcElem){
						out += srcElem + '/';
					}
				)
				largeSrc = out + 'large/' + image.substring(0, (image.length -4) ) + '.jpg';
				img.observe('click', function(){
					window.open(largeSrc);
				});
//				var instID = 'iClientBase' + parseInt(Math.random()*1000000);
//		    	var largeImg = new Element('img', {src:largeSrc, id:instID});
////		    	var link = new Element('a', {href:'#'+instID});
////		    	img.wrap(link);
//		    	img.href=largeSrc;
//
////		    	img.parentNode.insert(largeImg);
////		    	largeImg.hide();
//		    	
//		    		new FancyZoom(instID);
		    	
			}).bind(this)
		)
	}
