// JavaScript Document
/* 
 * author Vaclav Rak
 * vytvoreno Wednesday, November 21, 2007 18:02
 * kontakt rak@avast.com 
 * pro ALWIL Software
 *
 * $Log$
 *
 
 	declaration of basic objects
 */




function baseObject(){
	this.maintenanceCtrl = ""; 				// text id of maintenance contract
	this.currencyCtrl = "";					// text id of currency selector
	this.renewalCtrl = "";					// text id of renewal checkbox
	this.discountCtrl = "";					// text id of discount selector (health, charity, school, etc)
	this.customerTypeCtrl = "";				// customer type Id
	this.unlimitedFrom = -1;				// number of licences with constant price (SMTP, Linux)
	this.textUnlimited = 'unlimited';		// text when license is unlimited
	this.pricelistObject = null;			// the object for price matters
	this.customerTypeCtrl = ""; 			// text id if customer type (Home, Commercial)

	this.getInputValue = function (name){
		var domE = document.getElementById(name);
		if (!domE) alert("Error: " + this.name+" [getInputValue] element not found "+ name);
		
		if (typeof(domE.disabled) == 'undefined' || ( typeof(domE.disabled) != 'undefined'  && domE.disabled == false)){
			return domE.value;
		} else {
			//alert( domE.value);
			return 0;
			
		}
	}
	
	this.writeDebug = function(msg){
		var debug = document.getElementById('debug');
		debug.innerHTML += msg;
		debug.innerHTML += "<hr>";
	}
	this.getMaintenanceContract = function(){
		var val =  parseInt(this.getInputRadioValue(this.maintenanceCtrl));
		val = parseInt(val);
		if (!val) val = 1; 		
		return val;
	}
	this.makeDecimals = function(number){
		var  s = new String;
		if (isNaN(number)) return 'N/A';
		s = String(Math.round(number  * 100) / 100);
		var i = s.indexOf('.');
		if (i == -1) s += '.00';
		if (i == s.length - 2) s += '0';
		return s;
	} 
	this.getCurrency = function(){
		return  this.getInputValue(this.currencyCtrl);
	}

	this.getInputCheckValue = function (name){
		
		var domE = document.getElementById(name);
		if (!domE) alert("Error: " + this.name+" [getInputCheckValue] element not found "+ name);
		return domE.checked;
	}
	
	this.getInputRadioValue = function (name){
		var domEs = document.getElementsByTagName("input");
		var i = 0;
		for(i=0;i<domEs.length;i++){
			
			domE = domEs[i];
			if (domE.name == name) {
				if (domE.checked  == true) {
					return domEs[i].value;
				}
			}
		}
	}
	this.getDiscount = function(){
		var name  = this.discountCtrl;
		var domE = document.getElementById(name);
		if (!domE) { alert("Error: " + this.name+" [getInputCheckValue] element not found `"+ name  + "`"); return Nan; } 

		var val = parseInt(domE.value);
		var opt = domE.options[domE.selectedIndex];
		if (opt.getAttribute('withrenewal') != null && this.getInputCheckValue(this.renewalCtrl)) {
			val = parseInt(opt.getAttribute('withrenewal'));
		}
		this.productDiscountDescription = domE[domE.selectedIndex].text;
		
		this.productDiscount = val;
		return this.productDiscount;
	}
/*	
	this.getDiscount = function(){
		var val = this.getInputValue(this.discountCtrl);
		if (!val) val = 0; 		
		this.productDiscountDescription = "";
		if (val == 30) this.productDiscountDescription =  "Health care or goverment";
		if (val == 50) this.productDiscountDescription =  "Charity or education";
		
		this.productDiscount = val;
		return this.productDiscount;
	}
*/
	this.getLicenceNumber = function(){
		var val = this.getInputValue(this.inputControl);
		val = parseInt(val);
		if (!val) {
			val = 0;
		} 
		if (val > 0) {
			var minLic = parseInt(this.pricelistObject.getMinimalLicenses(this.InternalId));
			if (val < minLic) val = minLic;
		}
		return val;
	}
	this.getCustomerType = function(){
		var chkPersonal = this.getInputCheckValue(this.customerTypeCtrl)
		return (chkPersonal ? "home" : "commercial");
	}
	this.inA = function(arr, ix){
		for(var i in arr){
			if (arr[i] == ix) return true;
		}
		return false;
	}
	this.setCookie = function(c_name,value,expiredays){
		var exdate=new Date();
		exdate.setDate(exdate.getDate()+expiredays);
		document.cookie=c_name+ "=" +escape(value)+
		((expiredays==null) ? "" : ";expires="+exdate.toGMTString());
	}
	
	this.getCookie = function(c_name){
		if (document.cookie.length>0)	{
			c_start=document.cookie.indexOf(c_name + "=");
			if (c_start!=-1){ 
				c_start=c_start + c_name.length+1; 
				c_end=document.cookie.indexOf(";",c_start);
				if (c_end==-1) c_end=document.cookie.length;
				return unescape(document.cookie.substring(c_start,c_end));
			} 
		}
		return "";
	}
}
function productObject(inputCtrl, maintenanceCtrl, currencyCtrl, customerTypeCtrl, renewalCtrl, discountCtrl, InternalId){
	this.inheritFrom = baseObject;	
	this.inheritFrom();
	this.name = "productObject";
	this.productLabel = "";					// product label used on screen
	this.inputControl = inputCtrl; 			// text id of license number control
	this.maintenanceCtrl = maintenanceCtrl; // text id of maintenance contract
	this.currencyCtrl = currencyCtrl;		// text id of currency selector
	this.renewalCtrl = renewalCtrl;			// text id of renewal checkbox
	this.discountCtrl = discountCtrl;		// text id of discount selector
	this.customerTypeCtrl = customerTypeCtrl; // text id if customer type (Home, Commercial)

	this.currentLicences = 0;
	this.currentCurrency = "USD";
	this.currentMaintenance = 1;
	this.professionalResultDiv = null;		// Div element id for write results, if not defined nothing will be written anywhere
	this.InternalId = InternalId;			// internal Id from pricelist
	this.productRenewal = 0;				// current product renewal in percents
	this.originalPrice = 0;					// price without any discount
	this.renewalDiscountPrice = 0;			// renewal discount in money
	this.finalPrice = 0;					// the final price (read only for foreings)
	this.productDiscountDescription	= "";	// described description of discount
	this.productDiscount = 0;				// discount in percent
	this.productDiscountPrice = 0;			// discount in money
	
	this.setEvent = function (eName, value){
		var input = document.getElementById(this.inputControl);
		if (input) {
			var ev = "this."+eName+" = '"+value+"';";
			eval(ev);
		}
	}
	
	this.getRenewalByInternalId = function(internalId){
		//alert(this.name+", "+this.renewalCtrl);
		var renewal = this.getInputCheckValue(this.renewalCtrl);
		var renVal = 0;
		this.productRenewal  = 0;
		if (renewal){
			renVal = this.pricelistObject.getRenewal(internalId, this.getCurrency());
		} 
		return renVal;
	}

	this.getRenewal = function(){
		this.productRenewal = this.getRenewalByInternalId(this.InternalId)
		return this.productRenewal;
	}
	
	this.getMinLicenceNumber = function (licNo){
		pricelistMin = this.pricelistObject.getMinimalLicenses(this.InternalId);
		if (pricelistMin > licNo) licNo = pricelistMin;
		return parseInt(licNo);
	}
	this.getOriginalPrice = function(){ // method getPrice count originalPrice
		var licNo = this.getLicenceNumber();
		var inputControl = document.getElementById(this.inputControl);
		if (this.unlimitedFrom  == -1){
			this.unlimitedFrom= NaN;
			if (inputControl.getAttribute('unlimitedFrom') != 'undefined')  this.unlimitedFrom = parseInt(inputControl.getAttribute('unlimitedFrom'));
		}
		if (this.unlimitedFrom > 0 && licNo > this.unlimitedFrom) licNo = this.unlimitedFrom;
		return this.getPricePerLicence()  * licNo;
		
	}
	this.calculate = function (){
			//alert(this.getCurrency());
			this.originalPrice = this.getOriginalPrice(); 								// method getPrice count originalPrice
			this.renewalDiscountPrice = (this.getRenewal()/100) * this.originalPrice;
			this.finalPrice = this.originalPrice - this.renewalDiscountPrice;
			this.productDiscountPrice = (this.getDiscount()/100) * (this.finalPrice);
			this.finalPrice = this.finalPrice - this.productDiscountPrice;
			this.renewalDiscount = this.getRenewal();
			this.productDiscount  = this.getDiscount();

		this.writeResults();
		return this.finalPrice;
	}
	
	this.getPricePerLicence = function(){
		/* 
		//old version commented 2008-07-17  8:57 
		var price = NaN;
		var licNo = this.getLicenceNumber();
		if (licNo > 0){
			price = this.pricelistObject.getPricePerLicense(this.InternalId, this.getCurrency(), licNo, this.getMaintenanceContract());
		}
		return price;
		// old version commented 2008-07-17  8:57 
		*/
		var price = NaN;
		if (!isNaN(this.calculator.customerLicense[this.InternalId]) && this.getRenewal() == 0) {
			var licNo = this.getLicenceNumber() + parseInt(this.calculator.customerLicense[this.InternalId]);
		} else {
			var licNo = this.getLicenceNumber();
		}
		if (licNo > 0){
			price = this.pricelistObject.getPricePerLicense(this.InternalId, this.getCurrency(), licNo, this.getMaintenanceContract());
		}

		if (this.unlimitedFrom > 0 && licNo > this.unlimitedFrom) licNo = this.unlimitedFrom;
		if (licNo > 0){
			price = this.pricelistObject.getPricePerLicense(this.InternalId, this.getCurrency(), licNo, this.getMaintenanceContract());
		}

		//this.writeDebug('getPricePerLicence '+ this.InternalId +":  "+ price + ' x ' + licNo + ' = ' + price  * licNo);		
		
		return price;

	}
	
	this.setResultDiv = function(name){
		this.professionalResultDiv = document.getElementById(name);
	}
	
	this.setPricelist = function(pricelist){
		this.pricelistObject = pricelist;
	}
	this.writeResults = function(){
		if (this.professionalResultDiv ) {
			if (this.getLicenceNumber() > 0) {
				var tmpHtml = "";
				var currency = this.getCurrency();
				var licNo = this.getLicenceNumber() ;
				if (this.unlimitedFrom > 0 && licNo >= this.unlimitedFrom) licNo = this.textUnlimited;
				if (this.productRenewal ) {
					if (licNo == this.textUnlimited){
						tmpHtml = licNo  +   "&nbsp;-" + this.productRenewal + "%&nbsp;"+this.calculator.lblRenewal+" ";
					} else {
						tmpHtml = licNo  + "&nbsp;x&nbsp;" + this.makeDecimals(this.getPricePerLicence())+ "&nbsp;" + currency +   "&nbsp;-" + this.productRenewal + "%&nbsp;"+this.calculator.lblRenewal+" ";
					}
				} else {
					if (licNo == this.textUnlimited){
						tmpHtml = licNo  ;
					} else {
						tmpHtml = licNo  + "&nbsp;x&nbsp;" + this.makeDecimals(this.getPricePerLicence())+"&nbsp;" + currency;
					}
				}
				if (this.productDiscount > 0)
					this.professionalResultDiv.innerHTML = "("+tmpHtml + ")&nbsp;-" +this.productDiscount+"%&nbsp;"+this.productDiscountDescription+"&nbsp;=&nbsp;"+this.makeDecimals(this.finalPrice)+"&nbsp;" + currency;
				else
					this.professionalResultDiv.innerHTML = tmpHtml +"&nbsp;=&nbsp;"+this.makeDecimals(this.finalPrice)+"&nbsp;" + currency;

			} else {
				this.professionalResultDiv.innerHTML  = "";
			}
		}
	}
	
}

function netObject() {
	this.inheritFrom = baseObject;	
	this.inheritFrom();
	this.READY_STATE_UNINITIALIZED=0;
	this.READY_STATE_LOADING=1;
	this.READY_STATE_LOADED=2;
	this.READY_STATE_INTERACTIVE=3;
	this.READY_STATE_COMPLETE=4;
	this.name = "netObject";
	
	/*--- content loader object for cross-browser requests ---*/
	this.ContentLoader=function(url,onload,onerror,method,params,contentType,notification){
		this.req=null;
		this.onload=onload;
		this.onerror=(onerror) ? onerror : this.defaultError;
		this.msgId=1;
		this.loadXMLDoc = function(url,method,params,contentType){
			if (!method){
				method="GET";
			}
			if (!contentType && method=="POST"){
				contentType='application/x-www-form-urlencoded';
			}
			if (window.XMLHttpRequest){
				this.req=new XMLHttpRequest();
			} else if (window.ActiveXObject){
				this.req=new ActiveXObject("Microsoft.XMLHTTP");
			}
			if (this.req){
				try{
					var loader=this;
					this.req.onreadystatechange=function(){
						loader.onReadyState.call(loader);
					}
					this.req.open(method,url,true);
					if (contentType){
						this.req.setRequestHeader('Content-Type', contentType);
					}
					this.ContentLoader.msgId++;
					this.req.send(params);
				}catch (err){
					//alert(this.onerror);
					this.onerror(this);
				}
			}
		}
	
		this.onReadyState = function(){
			var req=this.req;
			var ready=req.readyState;
			if (ready==this.READY_STATE_COMPLETE){
				var httpStatus=req.status;
				if (httpStatus==200 || httpStatus==0){
					//this.notification.clear();
					this.onload();
				}else{
					this.onerror(this);
				}
			}
		}

		this.defaultError = function(){
			var msgTxt="error fetching data!"+"<ul><li>readyState:"+this.req.readyState+"<li>status: "+this.req.status+"<li>headers: "+this.req.getAllResponseHeaders()+"</ul>";
			if (this.notification){
				this.notification.clear();
			}
			this.notification=new msg.Message("net_err00"+this.ContentLoader.msgId, msgTxt,msg.PRIORITY_DEFAULT.id);
			this.ContentLoader.msgId++;
		}

		this.loadXMLDoc(url,method,params,contentType,notification);
		if (notification) {
			this.notification = notification;
		}  else {
			//this.notification=new msg.Message( "net00"+this.ContentLoader.msgId, "loading "+url, msg.PRIORITY_LOW.id, -1, "include/smarty/templates/msg/msg_run.gif" );
			//alert("net00"+this.ContentLoader.msgId+", loading "+ url);
		}
	}
}

function calculatorObject(controls, targetDivId){
	this.inheritFrom = netObject;	
	this.inheritFrom();
	this.pricesList = new Array();				// prices list cache
	this.controls = controls;				// control xml URL address
	this.contorlObj = null;					// control xml object
	this.targetDivId = targetDivId;			// target div Id 
 	this.name = "calculatorObject";
	this.ctrl = null;						// current control when building calculator
	this.pricelist = null; 					// refernce to pricelist object (initiate in pricelist object by callback) 
	this.chkUseProduct = new Array(); 		// list of checkboxes what enable control of product (whitch are by default disabled)
	this.ctrlInputList = new Array();		// list of input id of type text controls (the numbers of licenses)
	this.ctrlTargetInputId = new Array(); 	// list of products target
	this.disJointProducts = new Array();	// product what could not be select together
	this.productList = new Array();			// list of productObject in calculator
	this.licenceRequest = new Array();		// requested licenses for suite calculation
	this.productsRequest = new Array();				// list of productObject request
	this.calculatorResults="calculatorResults";		// calculator selected configuration result element id
	this.suiteTarget = 'suiteTarget';				// calculator suite result element id
	this.otherSuites = 'otherSuites';				// other solution in suite, just for debug
	this.exportButtons = 'exportButtons';			// text element id of export buttons toolbar
	this.suiteCollection = null;					// reference to suite collection object
	this.selectedConfiguration = new Array();		// result of selected configuration 
	this.unlimitedFromList = new Array();			// associative list of products with unlimited licenses option
	this.pdfUrl = "";								// base of PDF script (call via GET)
	this.beforeGenerateControl = null;				// event for handel generating controls
	this.afterGenerateControl = null;				// event for handel generating controls
	this.afterInitControls = null;					// event for initiate controls in inhrited calcularors
	this.beforeCallCalculate = null;				// event called from update control before calculate 
	this.customerLicense = new Array();				// number of already purchased licenses
	
	this.netError = function(){
		var msgTxt="Error fetching data!"+"<ul><li>readyState:"+this.req.readyState+"<li>status: "+this.req.status+"</li><li>headers: <pre>"+this.req.getAllResponseHeaders()+"</pre></li></ul>";
		alert(msgTxt);
	}
	

	
	this.calculate = function(){
		this.finalPrice = 0;
		

		for(ix in this.productsRequest){
			var prod = this.productsRequest[ix];
			//alert(prod.name + ", " +prod.InternalId);
			
			var tmpArr = new Object();
			if (prod.unlimitedFrom > 0) {
				var licNo = prod.getLicenceNumber();
				if (prod.unlimitedFrom > 0 && licNo > prod.unlimitedFrom) 
					tmpArr.configuration  = this.textUnlimited;
				else
					tmpArr.configuration  = prod.getLicenceNumber();
			} else {
				tmpArr.configuration  = prod.getLicenceNumber();
			}

			tmpArr.pricePerLicense  = prod.getPricePerLicence();
			tmpArr.originalPrice = prod.originalPrice;
			tmpArr.renewalDiscountPrice  = prod.renewalDiscountPrice;
			tmpArr.renewalDiscount  = prod.renewalDiscount;
			tmpArr.finalPrice  = prod.finalPrice;
			tmpArr.productDiscountPrice  = parseFloat(prod.productDiscountPrice);
			tmpArr.productDiscount  = prod.productDiscount;// alert( this.productDiscount);
			tmpArr.productDiscountDescription  = prod.productDiscountDescription;
			this.selectedConfiguration[prod.InternalId] = tmpArr;
			this.finalPrice+= tmpArr.finalPrice;
		}
		this.suiteCollection.cleanUp();
		this.suiteCollection.acceptRequest(this.licenceRequest);
		if (this.finalPrice < this.suiteCollection.getBestSolution()) {
			if (this.suiteCollection.bestSuite) this.suiteCollection.addOtherSolution(this.suiteCollection.bestSuite, this.suiteCollection.bestSuite.InternalId);
			this.suiteCollection.bestSuite = null;
		}
		this.writeResults();
		this.updateExports();
		
		return this.finalPrice;
	}
	this.w = function(s){
		if (this.targetDiv){
			this.targetDiv.innerHTML+= s;
		}
	}
	this.writeCurrecy = function(){
		var lines = "<label><h3 class='inline'>"+this.ctrl.getAttribute('label')+"</h3>";
		lines+= "<select name='"+this.ctrl.getAttribute('name')+"' id='"+this.ctrl.getAttribute('id')+"' onchange='this.calculator.updateControls();' onkeyup='this.calculator.updateControls();'>";
		this.currencyCtrl = this.ctrl.getAttribute('id');
		var currencyOptions = this.pricelist.xmlPricelist.getElementsByTagName('pricelist');
		var selectedCurrency  = 'USD';
		if (this.ctrl.getAttribute('default') != null) selectedCurrency = this.ctrl.getAttribute('default');
		if (this.getCookie('selectedCurrency') != '') selectedCurrency = this.getCookie('selectedCurrency');
		for(var j=0;j<currencyOptions.length;j++){
			var name = currencyOptions[j].getAttribute('currency');
			var id = this.ctrl.getAttribute('id') + name;
			var selected = "";
			if (selectedCurrency == name) selected =  " selected='selected' ";
			lines+= "<option value='"+name+"' id='"+id+"' " + selected + ">"+name+"</option>";
		}
		lines+= "</select></lable>";
		this.w(lines);		
	}
	this.writeDiscount = function(){
		var lines = "<label><h3 class='inline'>"+this.ctrl.getAttribute('label')+"</h3>";
		lines+= "<select name='"+this.ctrl.getAttribute('name')+"' id='"+this.ctrl.getAttribute('id')+"'  onchange='this.calculator.updateControls();' onkeyup='this.calculator.updateControls();'>";
		this.discountCtrl = this.ctrl.getAttribute('id');
		var discountOptions = this.ctrl.getElementsByTagName("option");
		for(var j=0;j<discountOptions.length;j++){
			var withRenewal = "";
			var name = discountOptions[j].getAttribute('name');
			var value = discountOptions[j].firstChild.nodeValue ;
			var id = this.ctrl.getAttribute('id') + name;
			//alert(discountOptions[j].getAttribute('withRenewal'));
			if (discountOptions[j].getAttribute('withRenewal') != null) {
				withRenewal = " withrenewal='"+discountOptions[j].getAttribute('withRenewal')+"' ";
			}
			lines+= "<option value='"+name+"' id='"+id+"' "+withRenewal+">"+value+"</option>";
		}
		lines+= "</select></lable>";
		this.w(lines);		
	}
	this.writeRenewal = function(){
		this.w("<label>"+this.ctrl.getAttribute('label')+"<input type='checkbox' id='"+this.ctrl.getAttribute('id')+"'  onClick='this.calculator.updateControls();' onKeyUp='this.calculator.updateControls();'/></label>");
		this.renewalCtrl = this.ctrl.getAttribute('id');
	}
	this.writeCustomerType = function(){
		this.w("<label>"+this.ctrl.getAttribute('label')+"<input type='checkbox' id='"+this.ctrl.getAttribute('id')+"'  onClick='this.calculator.updateControls();' onKeyUp='this.calculator.updateControls();' /></label><hr>");
		this.customerTypeCtrl = this.ctrl.getAttribute('id');
	}
	this.writeMaintenanceControl = function(){
		var lines = "<h3>"+this.ctrl.getAttribute('label')+"</h3>";
		this.maintenanceCtrl = this.ctrl.getAttribute('id');
		var mcOptions = this.ctrl.getElementsByTagName("option");
		for(var j=0;j<mcOptions.length;j++){
			var value = mcOptions[j].getAttribute('value');
			var content = mcOptions[j].firstChild.nodeValue ;
			var id = this.ctrl.getAttribute('id') ;
			var ch = "";
			if (value == 1) ch = " checked='checked' "
			lines+= "<label><h3 class='inline'><input type='radio' name='"+id+"' value='"+value+"' "+ch+" onClick=' this.calculator.updateControls();' onChange='this.calculator.updateControls();' onKeyUp='this.calculator.updateControls();'>"+content+"</h3></lable>";
		}
		lines+= "<hr>";
		//alert(lines);
		this.w(lines);		
	}
	this.unChekById = function(id){
		
		if (this.disJointProducts[id]){
			var elIds = this.disJointProducts[id].split('|');
			for(var r=0;r<elIds.length;r++){
				document.getElementById('chkUse'+elIds[r]).checked = false;	
			} 
		}
	}
	this.generateProductContainer = function(){
		var url = this.ctrl.getAttribute('url');
		var productName = this.ctrl.getAttribute('label');
		var lines = "";
		var id = this.ctrl.getAttribute('id');
		var customerType = "";
		if (this.ctrl.getAttribute('customer-type') != null){
			customerType  = "customerType='"+this.ctrl.getAttribute('customer-type')+"'";
		}
		lines+= "<h3><a href='"+url+"' title='"+productName+"' target='_blank'> "+productName+"</a></h3>";
		var content = this.ctrl.getAttribute('otherText'); //this.ctrl.firstChild.nodeValue ;
		var unlimitedFrom = "";
		if (this.ctrl.getAttribute('unlimited-from') != null) {
			unlimitedFrom = " unlimitedFrom='"+this.ctrl.getAttribute('unlimited-from')+"'";
			this.unlimitedFromList[this.ctrl.getAttribute('id')] = this.ctrl.getAttribute('unlimited-from');
		}
		var classAttr = "";
		if (this.ctrl.getAttribute('disjointProduct') !=null) {
			this.disJointProducts[id] = this.ctrl.getAttribute('disjointProduct');		
			classAttr = 'class="radio"';
		} 
		var useText = "";
		var disabled = "";
		//alert(this.ctrl.getAttribute('useText'));
		if (this.ctrl.getAttribute('useText')!=null) {
			useText = "<label>&nbsp;<input type='checkbox' "+classAttr+" name='chkUse"+id+"' id='chkUse"+id+"' onClick=' /*alert(this.name); */this.calculator.unChekById(\""+id+"\");  this.calculator.updateControls();'  onKeyUp=' this.calculator.updateControls(); ' >"+this.ctrl.getAttribute('useText')+"</label>";
			this.chkUseProduct.push('chkUse'+id+'|product'+id+"|"+this.ctrl.getAttribute('default'));
			lines+= useText;
			disabled = " disabled='disabled' ";
		}
		if (content.indexOf("{MIN}") > 0) {
			var minLic = this.pricelist.getMinimalLicenses(id);
			content = content.replace("{MIN}", minLic);
		}
		if (content.indexOf("{MAX}") > 0) {
			var minLic = this.pricelist.getMaximumLicenses(id, "USD", 199, 1);
			content = content.replace("{MAX}", minLic);
		}
		lines+= "<p>"+content+""
				
		lines+= "<input "+customerType+" class='productControl' type='text' name='product"+id+"' id='product"+id+"' value='0' oldValue='0' "+disabled+" onChange='if (this.oldValue != this.value) {this.oldValue = this.value; this.changed = true; this.calculator.updateControls(); }' onkeyup='if (this.oldValue != this.value) {this.oldValue = this.value; this.changed = true; this.calculator.updateControls(); }' "+unlimitedFrom+"/></p>";
		this.ctrlInputList.push("product"+id);
		lines+= "<div id='productTarget"+id+"' class='productTarget'></div>"
		return lines;
	}
	this.writeProduct = function(){
		var id = this.ctrl.getAttribute('id');
		var lines = "";
		if (this.ctrl.getAttribute('groupLabel') != null){
			lines+= "<h3>"+this.ctrl.getAttribute('groupLabel')+"</h3>";
		}
		var customerTypeClass = "";
		if (this.ctrl.getAttribute('customer-type') != null){
			customerTypeClass  = "class='"+this.ctrl.getAttribute('customer-type')+"'";
			
		}
		lines+= "<div id='productContainer"+id+"' "+customerTypeClass+" >";
		lines+= this.generateProductContainer();
		lines+= "</div>";
		this.ctrlTargetInputId.push("productTarget"+id);

		var customerTypes = this.ctrl.getElementsByTagName('customer-type');
		for(var i=0;i<customerTypes.length;i++){
			var ct = customerTypes[i];
			
			if (ct.getAttribute('id') != null)	{ id = ct.getAttribute('id'); this.ctrl.setAttribute('id', ct.getAttribute('id')); }
			if (ct.getAttribute('label') != null)	this.ctrl.setAttribute('label', ct.getAttribute('label'));
			if (ct.getAttribute('url') != null)	this.ctrl.setAttribute('url', ct.getAttribute('url'));
			if (ct.getAttribute('default') != null)	this.ctrl.setAttribute('default', ct.getAttribute('default'));
			if (ct.getAttribute('useText') != null)	this.ctrl.setAttribute('useText', ct.getAttribute('useText'));
			if (ct.getAttribute('otherText') != null)	this.ctrl.setAttribute('otherText', ct.getAttribute('otherText'));
			if (ct.getAttribute('customer-type') != null)	this.ctrl.setAttribute('customer-type', ct.getAttribute('customer-type'));
			lines+= "<div id='productContainer"+id+"' class='"+ct.getAttribute('customer-type')+"' >";
			lines+= this.generateProductContainer();
			lines+= "</div>";
			this.ctrlTargetInputId.push("productTarget"+ct.getAttribute('id'));
		} 
		return lines;		
	}
	
	this.checkSubControl= function(){
		var subControl= this.ctrl.getElementsByTagName('sub-control');
		var lines = "";
		if (subControl.length > 0){
			var tmpCtrl = this.ctrl;
			lines+= "<div class='subControl' style='display:none;'>"
			for(var subIndex=0;subIndex<subControl.length;subIndex++){
				this.ctrl = subControl[subIndex];
				lines += this.writeProduct();
			}
			lines+= "</div>"
			this.ctrl = tmpCtrl;
		}
		return lines;
	}
	

	this.updateControls = function(){
		//alert(this.name);
		var customerType = this.getCustomerType();
		var c = document.getElementById(this.targetDivId);
		var elements = c.getElementsByTagName("div");
		var oldControl  = null;
		var newControl  = null;
		var objCurrency = document.getElementById(this.currencyCtrl);
		this.setCookie('selectedCurrency', objCurrency.value, 365);
		for(var k=0;k<elements.length;k++){
			var e = elements[k];
			if ((e.className != customerType) && (this.inA( new Array('commercial', 'home'), e.className)) && (e.style['display'] == "block")) oldControl = e;
			if (e.className == 'commercial') e.style['display'] = "none";
			if (e.className == 'home') e.style['display'] = "none";
			if (e.className == customerType && e.style['display'] != "block") { e.style['display'] = "block"; newControl = e;} 
		}
		if (newControl && oldControl && (newControl != oldControl)) {
			var oldId = oldControl.getAttribute('id').substr("productContainer".length);
			var newId = newControl.getAttribute('id').substr("productContainer".length);
			//alert( oldControl.getAttribute('id') );
			var oInp = document.getElementById("product" + oldId );
			var nInp = document.getElementById("product" + newId );
			//alert(nInp.value +", "+ nInp.id +" : "+ oInp.value +", "+oInp.id); 
			nInp.value = oInp.value;
			nInp.disabled = oInp.disabled;
			nInp.changed = oInp.changed;
			oInp.value = 0;
			oInp.disabled = true;
			//alert(nInp.value +", "+ nInp.id +" : "+ oInp.value +", "+oInp.id); 
			var oChk = document.getElementById("chkUse" + oldId );
			var nChk = document.getElementById("chkUse" + newId );
			if (oChk && nChk) nChk.checked =  oChk.checked;
			oChk.checked = false;
		}
		for(chk  in this.chkUseProduct){
			var txControl = this.chkUseProduct[chk];
			var xCtrl= txControl.split("|");
			var chk = document.getElementById(xCtrl[0]);
			var inp = document.getElementById(xCtrl[1]);
			var parentDivId = "divProduct" + xCtrl[1].substr('product'.length);			
			var parentDiv  = document.getElementById(parentDivId);
			if (parentDiv) {
				var subDiv = parentDiv.getElementsByTagName("div");
				for(var k=0;k<subDiv.length;k++){
					if (subDiv[k].className == 'subControl'){
						var sc = subDiv[k];
						var chkResult = (chk.checked ? "block" : "none");
						sc.style["display"] = chkResult ;
					}
				}
			}
			inp.disabled = !chk.checked;
			//inp.readOnly = !chk.checked;
			if (!inp.changed) eval(xCtrl[2]);
		}
		this.licenceRequest = new Object();
		this.productsRequest = new Array();
		this.selectedConfiguration = new Array();
		for(ix in this.productList){
			var productId = this.productList[ix].InternalId;
			var elProduct = document.getElementById('product'+productId);
			//if (productId == 'SE') alert('elProduct.disabled: ' + (elProduct.disabled ? 'true' : 'false'));
			//if (productId == 'WHSE') alert('elProduct.disabled: ' + (elProduct.disabled ? 'true' : 'false'));
			this.productList[ix].calculate();
			if (this.productList[ix].getLicenceNumber() > 0 && elProduct.disabled == false) { 
				var tmpProd = this.productList[ix];
				
				this.licenceRequest[tmpProd.InternalId] = tmpProd.getLicenceNumber();
				this.productsRequest.push(tmpProd);
				
			}
		}
		if (this.beforeCallCalculate) this.beforeCallCalculate();
		this.calculate();			
	}
	
	this.getInputRadioValue = function (name){
		var domEs = document.getElementsByTagName("input");
		var i = 0;
		for(i=0;i<domEs.length;i++){
			
			domE = domEs[i];
			//if (typeof(domE.name)=='undefined') alert(domE);
			if ( domE.name == name) {
				if (domE.checked  == true) {
					return domEs[i].value;
				}
			}
		}
	}
	
	this.getProductObject = function(inp, internalId){
		var product = new productObject(this.ctrlInputList[inp], this.maintenanceCtrl, this.currencyCtrl, this.customerTypeCtrl, this.renewalCtrl, this.discountCtrl, internalId);
		return product
	}	
	this.initiateControlEvents = function(){
		for(chk  in this.chkUseProduct){
			var txControl = this.chkUseProduct[chk];
			var xCtrl= txControl.split("|");
			var chkEl = document.getElementById(xCtrl[0]);
			var inputEl = document.getElementById(xCtrl[1]);
			chkEl.calculator = this;
		}

		for(inp  in this.ctrlInputList){
			var inpEl = document.getElementById(this.ctrlInputList[inp]);
			inpEl.calculator = this;
			inpEl.changed = false;
			//alert(inpEl.id +" "+inpEl.calculator);			
			var internalId = this.ctrlInputList[inp].substr("product".length);
			var product = this.getProductObject(inp, internalId);
			product.customerTypeCtrl = this.customerTypeCtrl;
			product.setPricelist(this.pricelist);
			product.setResultDiv(this.ctrlTargetInputId[inp]);
			product.productLabel = this.pricelist.getName(internalId);			
			this.productList.push(product);
			product.calculator = this;			
		}
		
		var tmpCtrl = document.getElementsByName(this.maintenanceCtrl);
		
		for(var j=0;j<tmpCtrl.length;j++){
			tmpCtrl[j].calculator = this;
		}
		
		tmpCtrl = document.getElementById(this.customerTypeCtrl);
		tmpCtrl.calculator = this;
		
		tmpCtrl = document.getElementById(this.renewalCtrl);
		tmpCtrl.calculator = this;
		
		tmpCtrl = document.getElementById(this.discountCtrl);
		tmpCtrl.calculator = this;
		
		tmpCtrl = document.getElementById(this.currencyCtrl);
		tmpCtrl.calculator = this;
		if (this.afterInitControls) this.afterInitControls();
		
	}
	this.generateCalculator = function(){
		//alert(this.req.responseXML);
		this.contorlObj  = this.req.responseXML;
		this.targetDiv = document.getElementById(this.targetDivId);
		var controls = this.contorlObj.getElementsByTagName("control");
		var finishDiv = true;
		this.w("<div id='debug'></div>");
		for(var i=0;i<controls.length;i++){
			this.ctrl = controls[i];
			var handeled = false;
			
			if (this.beforeGenerateControl) handeled = this.beforeGenerateControl(this.ctrl);
			if (!handeled) { 
				if (this.ctrl.getAttribute('id') == 'currency') this.writeCurrecy();
				if (this.ctrl.getAttribute('id') == 'discount') this.writeDiscount();
				if (this.ctrl.getAttribute('id') == 'renewal') this.writeRenewal();
				if (this.ctrl.getAttribute('id') == 'customerType') this.writeCustomerType();
				if (this.ctrl.getAttribute('id') == 'maintenanceContract') this.writeMaintenanceControl();
				if (this.ctrl.getAttribute('type') == 'product') {
					var lines = "<div class='divProduct' id='divProduct" +this.ctrl.getAttribute('id')+"'>";
					var addLine = "<hr></div>";
					if (typeof(this.ctrl.groupWithNext) != 'undefined') {
						if (this.ctrl.getAttribute('groupWithNext') == 'true'){
							addLine = "";
							finishDiv = false;
						}
					} 
					if (addLine != "") finishDiv = true;
					
					lines += this.writeProduct();
					lines += this.checkSubControl();
					lines += addLine;
					this.w(lines);
				}
				if (this.ctrl.getAttribute('type') == 'label') {	
					this[this.ctrl.getAttribute('name')] = this.ctrl.getAttribute('value');	
					handeled = true;  
				}
			}
			if (this.afterGenerateControl) handeled = this.afterGenerateControl(this.ctrl);
		}
		
		this.w("<div id='"+this.calculatorResults+"'></div>");
		this.w("<div id='"+this.suiteTarget+"'></div>");
		this.w("<div id='"+this.exportButtons+"'></div>");
		this.w("<div id='"+this.otherSuites+"'></div>");
		this.ctrl = null;
		//alert(this.chkUseProduct);
		this.suiteCollection = this.getSuiteCollection();
		this.suiteCollection.init();
		//alert(this.suiteCollection);
		this.initiateControlEvents();
		this.updateControls();
	}
	this.prepareCalculator = function(pricelist){
		this.ContentLoader(this.controls, this.generateCalculator, this.netError );
	}
	this.getSuiteCollection = function(){
		return new suiteCollection(this);
	}
}

function pricelistObject(pricelist, /*product, */calculator ){
	this.inheritFrom = netObject;	
	this.inheritFrom();
	this.name = "pricelistObject";
	this.xmlPricelist = null;
	this.currencyList = null;
	this.errors = new Array();
	/*this.product = product;*/
	this.calculator = calculator;
	this.preparePricelist = function (){
		var o = this.req;
		this.xmlPricelist  = o.responseXML;
		this.getCurrencyList();
		
		if (this.calculator) {
			calculator.pricelist = this;
			calculator.prepareCalculator(this);
		}
	}

	this.getCurrencyList = function(){
		if (this.xmlPricelist) {
			if (!this.currencyList){
				elCurrencies = this.xmlPricelist.getElementsByTagName("pricelist");
				if (elCurrencies) {
					this.currencyList = new Array();
					for(i=0;i<elCurrencies.length;i++){
						this.currencyList[i] = elCurrencies[i];
					}
				} 
			} 
		} 
		return this.currencyList;
	}
	
	this.getRenewal = function(InternalId, Currency){
		//
		var renewal = 0;	
		if (this.xmlPricelist) {
			
			pricelist = this.getPricelist(Currency);
			if (!pricelist) {
				this.errors.push("Pricelist for currency '"+Currency+"' was not located.");
				return pricePerLicence;
			}
			family = this.getFamily(InternalId, pricelist);
			renewal = family.getAttribute('Renewal');
		} else this.errors.push("Pricelist is not ready,  wait for while ... ");
		return renewal;
	}
	this.getMinimalLicenses = function(InternalId){
		minimumLic = 0;

		var families = this.xmlPricelist.getElementsByTagName('family');
		var family = null;
		for(var fx=0;fx<families.length;fx++){
			if 	(families[fx].getAttribute('InternalId') == InternalId) {
				family	= families[fx];
				break;
			}
		}
		if (!family){
			this.errors.push("[getMinimalLicenses]  Product with InternalId: '"+InternalId+"' was not located in pricelist.");
			return minimumLic;
		}
		var products = family.getElementsByTagName("product");
		if (products.length > 0) {
			var product = products[0];
			minimumLic = this.getMinLicNumber(product);
		} else this.errors.push("\n<br>[getMinimalLicenses]  Product with InternalId: '"+InternalId+"' has not product element.");
		return minimumLic;
	}
	this.getMaximumLicenses = function(InternalId){
		maximumLic = 0;
		if (this.xmlPricelist) {
			var families = this.xmlPricelist.getElementsByTagName("family");
			var family = null;
			//if (InternalId == 'ADVS') alert(InternalId + ": " + 1);
			for(var ix=0;ix<families.length;ix++){
				if (families[ix].getAttribute('InternalId') == InternalId) {
					family = families[ix];
					break;
				}
			}
			//if (InternalId == 'ADVS')  alert(InternalId + ": " + 2);
			if (!family) {
				this.errors.push("[getMaximumLicenses] Product with internal id '"+InternalId+"' was not found in pricelist");
				return pricePerLicence;
			}
			var products = family.getElementsByTagName('product');
			var product = (products[0] ? products[0] : null);
			//if (InternalId == 'ADVS')  alert(InternalId + ": " + 3);
			if (!product) {
				this.errors.push("[getMaximumLicenses]  Product '"+family.getAttribute('product-family-name')+"' has not defined maintenance contract for '"+MaintenanceContract+"' year(s).");
				return pricePerLicence;
			}
			// if (InternalId == 'ADVS') alert(InternalId + ": " + 4);

			maximumLic = product.getAttribute("MaxQantity");
		}
//			alert(InternalId + " maximumLic: " + maximumLic);
		return maximumLic;
	}
	
	this.getMinLicNumber = function(product){
		var currentMinimum = 99999999999;
		var elPrices = product.getElementsByTagName("price");
		if (elPrices){
			for(var l=0;l<elPrices.length;l++){
				//alert(elPrices[l].getAttribute('min-quantity') + " < " + currentMinimum);
				if (parseInt(elPrices[l].getAttribute('min-quantity')) <  parseInt(currentMinimum)) {
					currentMinimum = elPrices[l].getAttribute('min-quantity');
				}
			}	
		}
		return parseInt(currentMinimum);
	}

	this.getNextLevel = function(InternalId, licNo){
		if (!licNo) return NaN;
		var retVal = 0;
		var families = this.xmlPricelist.getElementsByTagName("family");
		var family = null;
		for(var ix=0;ix<families.length;ix++){
			if (families[ix].getAttribute('InternalId') == InternalId) {
				family = families[ix];
				break;
			}
		}
		if (!family) {
			this.errors.push("[getMaximumLicenses] Product with internal id '"+InternalId+"' was not found in pricelist");
			return pricePerLicence;
		}
		var products = family.getElementsByTagName('product');
		var prod = products[0];
		retVal = prod.getAttribute('MaxQantity');
		var prices = prod.getElementsByTagName('price');
		for(var ix=0;ix<prices.length;ix++){
			var price = prices[ix];
			var minq = parseInt(price.getAttribute('min-quantity') );
			if (licNo < minq && retVal > minq )  retVal = minq ;
			//alert("licNo: "+ licNo + ", attribute min: " + minq  + ", retVal" + retVal);
		}
		//if (InternalId == 'STDS') alert("STDS next level: " + retVal);
		return retVal;
	}
	
	
	
	this.getFamily = function(InternalId, pricelist){
		family = null;
		//alert(pricelist.getAttribute('currency'))
		elFamilies = pricelist.getElementsByTagName("family");
		if (elFamilies) {
			for(var j=0;j<elFamilies.length;j++){
				if (elFamilies[j].getAttribute('InternalId') == InternalId) {
					family = elFamilies[j];
					break;
				}
			}
		}
		return family;
	}

	this.getProduct = function (MaintenanceContract, family){
		product = null;
		elProducts = family.getElementsByTagName("product");
		if (elProducts) {
			for(var k=0;k<elProducts.length;k++){
				if (elProducts[k].getAttribute('maintenance') == MaintenanceContract)	{
					product = elProducts[k];
					break;
				}
			}
		}
		return product;		
	}

	this.getPricelist = function(Currency){

		pricelist = null;
		elCurrencies = this.xmlPricelist.getElementsByTagName("pricelist");
		if (elCurrencies) {
			for(var i=0;i<elCurrencies.length;i++){
				if (elCurrencies[i].getAttribute('currency') == Currency) {
					pricelist = elCurrencies[i];	
					break;
				}
			}
		} 
		return pricelist;
	}
	
	this.getPrice = function(LicenceNumber, product){
		pricePerLicence = NaN;
		elPrices = product.getElementsByTagName("price");
		if (elPrices){
			for(var l=0;l<elPrices.length;l++){
				if (parseInt(elPrices[l].getAttribute('min-quantity')) <= parseInt(LicenceNumber)) {
					pricePerLicence = parseFloat( elPrices[l].getAttribute('per-license') );
					//this.calculator.writeDebug(product.getAttribute("label") +", Price: "+pricePerLicence+",   LicenseNumber: "+ LicenceNumber+", min qantity: " + elPrices[l].getAttribute('min-quantity'));
				}
			}	
		}
		return pricePerLicence;
	}
	
	this.getPricePerLicense = function(InternalId, Currency, LicenceNumber, MaintenanceContract){
		pricePerLicence = NaN;
		if (!LicenceNumber) return pricePerLicence;
		//alert(this.pricesList);
		if (this.pricesList && 
			this.pricesList[InternalId] && 
			this.pricesList[InternalId][Currency] && 
			this.pricesList[InternalId][Currency][LicenceNumber] && 
			this.pricesList[InternalId][Currency][LicenceNumber][MaintenanceContract]){
				pricePerLicence = this.pricesList[InternalId][Currency][LicenceNumber][MaintenanceContract];
		}else{
			if (this.xmlPricelist) {
	
				var pricelist = this.getPricelist(Currency);
				
				if (!pricelist) {
					this.errors.push("[getPricePerLicense] Pricelist for currency '"+Currency+"' was not located.");
					return pricePerLicence;
				}
				var family = this.getFamily(InternalId, pricelist)
				if (!family) {
					this.errors.push("[getPricePerLicense] Product with internal id '"+InternalId+"' was not found in pricelist");
					return pricePerLicence;
				}
				var product = this.getProduct(MaintenanceContract, family);
				if (!product) {
					this.errors.push("[getPricePerLicense] Product '"+family.getAttribute('product-family-name')+"' has not defined maintenance contract for '"+MaintenanceContract+"' year(s).");
					return pricePerLicence;
				}
				if (product.getAttribute("MaxQantity") < LicenceNumber){
					this.errors.push("[getPricePerLicense] Product '"+family.getAttribute('product-family-name')+"' has defined maximum license number to  '"+product.getAttribute("MaxQantity")+"' your request is '"+LicenceNumber+"'.");
					return pricePerLicence;
				}
				pricePerLicence = this.getPrice(LicenceNumber, product);
				
				if (typeof(this.pricesList) == 'undefined')					
					this.pricesList = new Array();
				if (typeof(this.pricesList[InternalId]) == 'undefined')					
					this.pricesList[InternalId] = new Array();
				if (typeof(this.pricesList[InternalId][Currency]) == 'undefined') 										
					this.pricesList[InternalId][Currency] = new Array();
				if (typeof(this.pricesList[InternalId][Currency][LicenceNumber]) == 'undefined') 							
					this.pricesList[InternalId][Currency][LicenceNumber] = new Array();
				if (typeof(this.pricesList[InternalId][Currency][LicenceNumber][MaintenanceContract]) == 'undefined') 	
					this.pricesList[InternalId][Currency][LicenceNumber][MaintenanceContract] = new Array();
	
				this.pricesList[InternalId][Currency][LicenceNumber][MaintenanceContract] = pricePerLicence;
			} else this.errors.push("[getPricePerLicense] Pricelist is not ready,  wait for while ... ");
		}
		return pricePerLicence;
	}
	
	this.getName = function(InternalId){
		var retVal = "";
		if (this.xmlPricelist) {
			elProducts = this.xmlPricelist.getElementsByTagName("family");
			for(var k=0;k<elProducts.length;k++){
				if (elProducts[k].getAttribute('InternalId')  == InternalId) {
					retVal  = elProducts[k].getAttribute('product-family-name');
					break;
				}	
			}
		} else this.errors.push("[getName] Pricelist is not ready,  wait for while ... ");
		return retVal;
	}
	this.getShareitId = function(InternalId, MC){
		var shareitId = 0;
		if (this.xmlPricelist) {
			var families = this.xmlPricelist.getElementsByTagName("family");
			var family = null;
			for(var l=0;l<families.length;l++){
				f = families[l];
				if (f.getAttribute('InternalId') == InternalId){
					family = f;
					break;
				}
			}
			if (!family) return -1;
			var products = family.getElementsByTagName("product");

			for(var k=0;k<products.length;k++){
				p = products[k];
				
				if (p.getAttribute('maintenance') == MC ) {
					return p.getAttribute('id');
					break;
				}
			}
		} else this.errors.push("[getPricePerLicense] Pricelist is not ready,  wait for while ... ");
		return shareitId;
	}
	this.ContentLoader(pricelist, this.preparePricelist );



}



