/*Global variables*/
var monthdays = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
/*End global variables*/

/*Global functions*/
//Check the leap year
function checkLeapYear(yyyy) {
	if(yyyy%4==0 && (yyyy%100!=0 || yyyy%400==0)) 
   		return true;
	else
		return false;
}

//Maximum value of days as a function of month and year
function getMaxDays(month,year) {
	if(month==1) {
	    if(checkLeapYear(year))
	        monthdays[1]=29;
	    else
	        monthdays[1]=28;
	}
	
	if(month>11)
	    return -1;
	else
	    return monthdays[month];           
}

//Check if date is correct
function checkDateCorrect(dd,mm,yyyy) {
    var day = parseInt(dd);
    var month = parseInt(mm);
    var year = parseInt(yyyy);

	//alert(mm);
    
    if ((day<0 || day>31) || (month<0 || month>11)  || !year)
        return false;

    if (day > getMaxDays(month,year))
        return false;

    return true;
}

//Help functions
function trim(value) {   
    var temp = value;   
 	
	var obj = /^(\s*)([\W\w]*)(\b\s*$)/;   
	if (obj.test(temp)) { 
		temp = temp.replace(obj, '$2');
 	}   
	var obj = / +/g;   
	temp = temp.replace(obj, " ");
	if (temp == " ") { temp = ""; }   
	return temp;
}

//Functions for Rollover effects
function MM_swapImgRestore() { //v3.0
  var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc;
}

function MM_preloadImages() { //v3.0
  var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
    var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
    if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
}

function MM_findObj(n, d) { //v4.01
  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
  if(!x && d.getElementById) x=d.getElementById(n); return x;
}

function MM_swapImage() { //v3.0
  var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)
   if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}
}

//Function for coockies
function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function eraseCookie(name) {
	createCookie(name,"",-1);
}

//POP-UP windows
function openWindow(url) {
    if (url != '') {
		var w = open(url);
		if(w)
		{
			w.focus();
		}
	}
}

//Delay code execution
function pause(millis) {
	var date = new Date();
	var curDate = null;

	do { curDate = new Date(); } 
	while(curDate-date < millis);
}
/*End global functions*/

/*Definition of class NCMPage.
  This class represents the object model of Nivaria Content Manager page*/
function NCMPage(id, name, url, homepath) {
	var m_id = id;							//Id of page
	var m_name = name;						//Name of page
	var m_url = url;						//Url of page
	var m_home = homepath;					//HOME path for files
	
    var m_fontSizes = [];					//Array of possible font sizes for page
    var m_curSize = -1;						//Current font size index
    
    var m_hasLateral = true;				//Has the page right lateral?
    
    var m_jsLibs = new collection();		//Collection of used JavaScript files
    var m_cssFiles = new collection();		//Collection of used CSS files

    //Variables to show and hide lists	
	var delayAvantDeCacher = 500; // in miliseconds
    var m_idTimer;
    
    //Dates constants
    var m_arrDays = new Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday");
    var m_arrMonths = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
    
    var m_fileboxes = new Array();			//Fileboxes of this page	

	var m_referrer = "";					//The referrer page for this page	

	//Creating cookie for history ( document.referrer work only for <a href="..."> in IE)
	var histValues = readCookie("pagesHistory");
	var pgName = m_url;
	if(pgName.lastIndexOf("/")!=-1)
		pgName = pgName.substr(pgName.lastIndexOf("/")+1);
	if(histValues==null) {
		createCookie("pagesHistory",pgName,1);
	} else {
		var arrPages = histValues.split("|");
		if(arrPages.length==1) {
			m_referrer = histValues;
			createCookie("pagesHistory",histValues+"|"+pgName);
		} else {
			m_referrer = arrPages[1];
			createCookie("pagesHistory",arrPages[1]+"|"+pgName);
		}
	}
	
	//Public read-only properies
	this.getId = function() {
		 return m_id;
	}
	
	this.getName = function() {
		 return m_name;
	}
	
	this.getUrl = function() {
		 return m_url;
	}
	
	this.getHasLateral = function() {
		return m_hasLateral;
	}
	
	this.getReferrer = function() {
		return m_referrer; 
	}
	
	//*****************************************
	//Public methods of NCMPage
	//*****************************************
	//Get the browser name
	this.getBrowser = function() {
		function checkIt(string) {
			return navigator.userAgent.toLowerCase().indexOf(string) + 1;
		}
		
        var browser;
        if (checkIt('konqueror')) browser = "Konqueror";
		else if (checkIt('safari')) browser = "Safari";
        else if (checkIt('omniweb')) browser = "OmniWeb";
        else if (checkIt('opera')) browser = "Opera";
        else if (checkIt('webtv')) browser = "WebTV";
        else if (checkIt('icab')) browser = "iCab";
        else if (checkIt('msie')) browser = "Internet Explorer";
        else if (!checkIt('compatible')) browser = "Netscape Navigator";
        else browser = "An unknown browser";
        return browser;
    }
    
    //Init array of font sizes and current font size for page
    this.initFontSizes = function(arrSize,index) {
   	 m_fontSizes = arrSize;
   	 m_curSize = index;
    }
    
    //Change the current font size on the page
    this.changeStyles = function(size) {
   	 if(!m_fontSizes.length) return;
	    if(size==1) {
		    if (m_curSize<m_fontSizes.length-1) {
			    m_curSize++;
			    document.body.style.fontSize = m_fontSizes[m_curSize];
		    }
	    } else {
		    if (m_curSize>0) {
			    m_curSize--;
			    document.body.style.fontSize = m_fontSizes[m_curSize];
		    }
	    }
    }
    
    
    this.onload = function() {
   	 //initMenu();
   	 //initLanguageChange();
   	 //initFontSize();
    }
    
    this.onruncomponents = function() {
   	 this.detectFileboxType();
		var params = document.location.search;
		if(params!="") {
			params = params.substr(1);
   		 var pars = new collection();
   		 var arr = params.split("&");
   		 if(arr!=null && arr.length>0) {
   			 for(var i=0;i<arr.length;i++) {
   				 var arr1 = arr[i].split("=");
   				 if(arr1!=null && arr1.length>1) {
   					 pars.add(arr1[0],arr1[1]);
   				 }
   			 }
   		 }
   		 if(pars.size()>0) {
   			 var action = pars.get("action");
   			 if(action!=null) {
   				 switch(action) {
   					 case "confirm":
   						 var objId = pars.get("objId");
   						 if(objId!=null) {
   							 var obj = ncmMngr.getComponent(objId);
   							 if(obj!=null) {
   								 var prdId = pars.get("prdId");
   								 if(prdId!=null) {
   									 obj.confirms(prdId);
   								 }
   							 }
   						 }
   						 break;
   					 default: 
   						 break;	 
   				 }
   			 }
   		 }
   	 }   	 
    }
    
    //Hiding and showing elements
    this.showElement = function(parentId, elemId) {
        var items = Array();
        items[0] = document.getElementById(parentId);
        items[1] = document.getElementById(elemId);
        if(items[1]==null) 
            return;		 
        if(items[0]!=null) {
            items[1].style.left = NCMPage.findPosX(items[0])+"px";
            items[1].style.top = (NCMPage.findPosY(items[0])+Element.getHeight(items[0]))+"px";
        }           

        if (items[1].style.visibility == "visible")
            items[1].style.visibility = "hidden";
        else {
            items[1].style.visibility = "visible";
            items[1].style.display = "block";
            items[1].style.zIndex=1;
        }
    }
    
    this.hideElement = function(name) {
		if(document.getElementById(name)!=null) document.getElementById(name).style.visibility = "hidden"; 
    }
    
    this.timerDebut = function(name) {
        m_idTimer = setTimeout("thisPage.hideElement("+name+")", delayAvantDeCacher);
    }

    this.timerFin = function() {
        clearTimeout(m_idTimer);
    }
    
    this.setDays = function(arr) {
        m_arrDays = arr;
    }
    
    this.setMonths = function(arr) {
        m_arrMonths = arr;
    }
    
    this.setHasLateral = function(val) {
		m_hasLateral = val;
	}
	
	this.addJavaScript = function(jsFile) {
		if(m_jsLibs.getIndex(jsFile)==-1) {
			document.write('<script type="text/javascript" src="'+jsFile+'"></script>');
			m_jsLibs.add(jsFile,jsFile);
		}		
	}
	
	this.addStyleSheet = function(cssFile) {
		if(m_cssFiles.getIndex(cssFile)==-1) {
			document.write('<link href="'+cssFile+'" rel="stylesheet" type="text/css"/>');
			m_cssFiles.add(cssFile,cssFile);
		}		
	}
	
	this.addFileBox = function(id,url) {
		m_fileboxes[m_fileboxes.length]= new dataFiles(id,url);
	}
	
	this.detectFileboxType = function()  {
		for (var i=0; i<m_fileboxes.length; i++) {
			detectFileType(m_fileboxes[i].id, m_fileboxes[i].url);
		}
	}
	
	this.getLinkInput = function(elemId,inputId,buttonId,buttonText,listId,typeName,delButtonText,titleId) {
		if(document.getElementById(elemId)==null) return;	
		document.getElementById(elemId).innerHTML = "<input type=\"text\" name=\""+inputId+"\" id=\""+inputId+"\" value=\"\"/>\n";
       	 document.getElementById(elemId).innerHTML += "<input type=\"button\" name=\""+buttonId+"\" value=\""+buttonText+"\" onclick=\"thisPage.addElementToList('"+inputId+"','"+listId+"','link','"+typeName+"','"+delButtonText+"','"+titleId+"');\" onkeypress=\"thisPage.addElementToList('"+inputId+"','"+listId+"','link','"+typeName+"','"+delButtonText+"','"+titleId+"');\"/>";
	}
	
	this.getFileInput = function(elemId,inputId,buttonId,buttonText,listId,typeName,delButtonText,titleId,formId) {
		if(document.getElementById(elemId)==null) return;	
		document.getElementById(elemId).innerHTML = "<input type=\"file\" name=\""+inputId+"\" id=\""+inputId+"\" value=\"\"/>\n";
       	 document.getElementById(elemId).innerHTML += "<input type=\"button\" name=\""+buttonId+"\" value=\""+buttonText+"\" onclick=\"thisPage.uploadFile('"+inputId+"','"+formId+"');thisPage.addElementToList('"+inputId+"','"+listId+"','file','"+typeName+"','"+delButtonText+"','"+titleId+"');\" onkeypress=\"thisPage.uploadFile('"+inputId+"','"+formId+"');thisPage.addElementToList('"+inputId+"','"+listId+"','file','"+typeName+"','"+delButtonText+"','"+titleId+"');\"/>";
	}
	
	this.addElementToList = function(from,to,type,typeName,buttonText,titleId,isTitleOblig) {
		if(document.getElementById(from)==null || document.getElementById(to)==null) return;
		var val = trim(document.getElementById(from).value);
		if(val=="") return;
		var title = "";
		try {
			title = trim(document.getElementById(titleId).value);
		} catch(mErr) {
		}
		if(isTitleOblig && title=="") {
			alert("Tiene que poner el titulo del fichero. Es obligatorio.");
			return;
		}
		if(title=="") title=val;
		
		this.addElementToListAdv(to,val,title,type,typeName,buttonText,"-1");
		
		try {
			document.getElementById(from).value = "";
			document.getElementById(titleId).value = "";
		} catch(mErr) {
		}
	}
	
	this.addElementToListAdv = function(to,val,title,type,typeName,buttonText,dbid) {
		var mUl = document.getElementById(to);
		var index = mUl.childNodes.length;
		var newId = 0;
		if(index>0) {
			var chld = mUl.childNodes[index-1];
			while(!(chld.nodeType==1 && chld.nodeName.toUpperCase()=="LI")) {
				chld = chld.previousSibling;
				if(chld==null) break;
			}
			if(chld!=null) {	
				var lastElId = chld.getAttribute("id");
				var arr = lastElId.split("_");
				if(arr.length>1)
					newId = parseInt(arr[1])+1;
			}		 
		}
		
		var mLi = document.createElement("LI");
		mLi.setAttribute("id",to+"_"+newId);
		
		var res = "<table width=\"100%\" height=\"20\" cellpadding=\"0\" cellspacing=\"0\">\n";
		res += "<tr bgcolor=\"#F7F6F9\">\n";
		res += "<td>\n";
		res += "<div style=\"float:right;margin-right:6px;width:20%;\">"+typeName+"</div>\n";
		res += "<div id=\"val"+to+"_"+newId+"\" style=\"float:left;width:75%;display:none;\" title=\""+title+"\">"+val+"</div>\n";
		res += "<div id=\"title"+to+"_"+newId+"\" style=\"float:left;width:75%;\" title=\""+val+"\">"+title+"</div>\n";
		res += "<div id=\"dbid"+to+"_"+newId+"\" style=\"display:none;\">"+dbid+"</div>\n";
		res += "</td>\n";
		res += "<td width=\"20\">\n";
		res += "<input type=\"button\" name=\"del"+to+"_"+newId+"\" value=\"X\" title=\""+buttonText+"\" onclick=\"thisPage.delElementFromList('"+to+"','"+to+"_"+newId+"');\" onkeypress=\"thisPage.delElementFromList('"+to+"','"+to+"_"+newId+"');\"/>\n";
		res += "</td>\n";
		res += "</tr>\n";
		res += "</table>\n";
		res += "<input type=\"hidden\" name=\"type"+to+"_"+newId+"\" id=\"type"+to+"_"+newId+"\" value=\""+type+"\"/>\n";
		 
		mLi.innerHTML = res;
		mUl.appendChild(mLi);
		
		Sortable.create(to,{});
	}
	
	this.delElementFromList = function(lst,elem) {
		var mUl = document.getElementById(lst);
		if(mUl==null) return;
		var mLi = document.getElementById(elem);
		if(mLi==null) return;
		mUl.removeChild(mLi);
	}
	
	this.delAllElementsFromList = function(lst) {
		var mUl = document.getElementById(lst);
		if(mUl==null) return;
		mUl.innerHTML = "";
	}
	
	this.uploadFile = function(inputId,formId,keyId) {
		if(document.getElementById(inputId)==null) return;
		var fileName = trim(document.getElementById(inputId).value);
		if(fileName=="") return;
		if(keyId==null || keyId=="") keyId="key";
		
		var frm = document.getElementById(formId);
		if(frm!=null) {
			var inp = document.getElementById(keyId);
			if(inp!=null) inp.value = inputId; 
			var w = window.open('about:blank','filesupload','width=250,height=75,left=300,top=300,toolbar=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=no,modal=yes');
			w.document.write("<html lang=\"en\" xml:lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\"/><title>Files upload...</title><style>h3 {	margin: 6px 0 6px 0; font-size: 1.0em;} div.progress {float:left;width:100%;height: 24px;border: 1px solid #CCCCCC;}</style></head><body><h3>Uploading files</h3><div class=\"progress\">Uploading file... Please wait...</div></body></html>");

	   		frm.target = 'filesupload';
   			frm.submit();
		}	
	}

	//Private functions	
	function dataFiles(id,url) {
		this.id = id;
		this.url = url;
	}
	
	function detectFileType(id,url) {
		var lasurl = url.split(".");
		var extension = lasurl[lasurl.length-1];
		var elem = document.getElementById(id);
		if(elem==null) return; 
		var titulo = url.split("/");
		
	      //var res = '<img title="'+titulo[titulo.length-1]+'" alt="'+titulo[titulo.length-1]+'" src="'+m_home+'/img/filebox/';
	      var res = '<img src="'+m_home+'/img/filebox/';
		switch(extension) {
			case "jpg":
			case "gif":
			case "png":
			case "bmp":
				res += 'file_img.gif" alt="'+extension+'" title="'+extension+'" />'
				break;
			case "doc":
			case "dot":
				res += 'file_doc.png" alt="'+extension+'" title="'+extension+'" />';
				break;
			case "pdf":
				res += 'file_pdf.gif" alt="'+extension+'" title="'+extension+'" />';
				break;
			case "ppt":
			case "pps":
				res += 'file_ppt.png" alt="'+extension+'" title="'+extension+'" />';
				break;
			case "swf":
				res += 'file_flash.gif" alt="'+extension+'" title="'+extension+'" />';
				break;
			case "xls":
				res += 'file_xls.png" alt="'+extension+'" title="'+extension+'" />';
				break;
			case "zip":
				res += 'file_zip.png" alt="'+extension+'" title="'+extension+'" />';
				break;
			case "xml":
				res += 'file_xml.gif" alt="'+extension+'" title="'+extension+'" />';
				break;					
			default:
			      //res += 'file_file.gif"/>.' + extension;
			      res += 'file_file.gif" alt="'+extension+'" title="'+extension+'" />';
				break;	
		}
		elem.innerHTML = res;
	}
}	

//Static methods
NCMPage.findPosX = function(obj) {
			var curleft = 0;
			if (obj.offsetParent) {
				 while (obj.offsetParent) {
				 		curleft += obj.offsetLeft
						obj = obj.offsetParent;
				 }
			} else if (obj.x)
						curleft += obj.x;
			return curleft;
}

NCMPage.findPosY = function(obj) {
			var curtop = 0;
			if (obj.offsetParent) {
				 while (obj.offsetParent) {
				 		curtop += obj.offsetTop
						obj = obj.offsetParent;
				}
			} else if (obj.y)
						curtop += obj.y;
			return curtop;
}

//Function for navigation lists
NCMPage.formNavListPages = function(curPos,total) {
    return NCMPage.formNavListPagesAdv(curPos,total,3);
}

NCMPage.formNavListPagesAdv	= function(curPos,total,PG_GROUP) {
    var PG_TOTAL=PG_GROUP*3+2;
    var maxArrElem=(total<PG_TOTAL) ? total : PG_TOTAL;
    var arPg = new Array(maxArrElem);

    if(total<=PG_TOTAL)
        for(var i=0;i<total;i++) arPg[i] = ""+i;
    else {
        if(curPos<PG_GROUP*2 || (curPos>=total-PG_GROUP*2 && curPos<total)) {
            if(curPos<PG_GROUP*2) {
                for(var k=0;k<PG_TOTAL;k++) {
                    if(k<=PG_GROUP*2) arPg[k]=""+k;
                    if(k==PG_GROUP*2+1) arPg[k]="";
                    if(k>PG_GROUP*2+1) arPg[k]=""+(total-(PG_TOTAL-k));
                }
            }
            if(curPos>=total-PG_GROUP*2 && curPos<total)
            {
                for(var k=0;k<PG_TOTAL;k++)
                {
                    if(k<PG_GROUP) arPg[k]=""+k;
                    if(k==PG_GROUP) arPg[k]="";
                    if(k>PG_GROUP) arPg[k]=""+(total-(PG_TOTAL-k));
                }
            }
        }
        else
        {
            for(var k=0;k<PG_TOTAL;k++)
            {
                if(k<PG_GROUP) arPg[k]=""+k;
                if(k==PG_GROUP) arPg[k]="";
                if(k>PG_GROUP*2+1) arPg[k]=""+(total-(PG_TOTAL-k));
                if(k==PG_GROUP*2+1)arPg[k]="";
                if(k>PG_GROUP && k<PG_GROUP*2+1) arPg[k]=""+(curPos-(PG_GROUP*2+1-k)+2);
            }
            if(parseInt(arPg[PG_GROUP+1])-parseInt(arPg[PG_GROUP-1])==2)
                arPg[PG_GROUP]=""+(parseInt(arPg[PG_GROUP-1])+1);
            if(parseInt(arPg[PG_GROUP*2+2])-parseInt(arPg[PG_GROUP*2])==2)
                arPg[PG_GROUP*2+1]= ""+(parseInt(arPg[PG_GROUP*2])+1);
        }
    }
    return arPg;
}	
/*End of NCMPage class definition*/


/*Definition of class NCMComponentManager.
  This class serve for manage components of Nivaria Content Manager.*/
function NCMComponentManager(parentPage) {
		var objects = new collection();
		var parent = parentPage;
		
		//Public read-only properties
		this.getPage = function() {
			return parent;
		}
		
		//Public methods
		this.createComponent = function() {
			var id = (arguments.length>0?arguments[0]:-1);
			var type = (arguments.length>1?arguments[1]:"");
			var tpl = (arguments.length>2?arguments[2]:"");
			if(id==-1 || type=="") {
				alert("Cannīt create NCM component object. The id of component or its type is incorrect.");
				return;
			}	
			var obj = null;
			try {
				obj = eval("new "+type+"(id,type,parent,tpl)");
			}
			catch(mErr){
				alert(mErr.description);
			}
			if(obj!=null) {
					objects.add(""+id,obj);
			}
		}
		
		this.getComponent = function(id) {
			var res = objects.get(""+id);
			if(typeof(res)=="undefined") res=null; 
			return res;
		}
		
		this.getComponents = function() {
		    return objects;
		}
		
		this.getComponentsByType = function(type) {
		    var res = new collection();
		    for(var i=0;i<objects.size();i++) {
		        var obj = objects.item(i);
		        if(obj.getType()==type) {
		            res.add(""+obj.getId(),obj);
		        }
		    }
		    return res;
		}
		
		this.getComponentsByTypeAndTemplate = function(type,tmName) {
		    var res = new collection();
		    for(var i=0;i<objects.size();i++) {
		        var obj = objects.item(i);
		        if(obj.getType()==type && obj.getTemplate()==tmName) {
		            res.add(""+obj.getId(),obj);
		        }
		    }
		    return res;
		}
}

function CCallWrapper(aObjectReference,aDelay,aMethodName,aArgument0,aArgument1,aArgument2,aArgument3,aArgument4,aArgument5,aArgument6,aArgument7,aArgument8,aArgument9) {
  this.mId = 'CCallWrapper_' + (CCallWrapper.mCounter++);
  this.mObjectReference = aObjectReference;
  this.mDelay     = aDelay;
  this.mTimerId = 0;
  this.mMethodName = aMethodName;
  this.mArgument0 = aArgument0;
  this.mArgument1 = aArgument1;
  this.mArgument2 = aArgument2;
  this.mArgument3 = aArgument3;
  this.mArgument4 = aArgument4;
  this.mArgument5 = aArgument5;
  this.mArgument6 = aArgument6;
  this.mArgument7 = aArgument7;
  this.mArgument8 = aArgument8;
  this.mArgument9 = aArgument9;
  CCallWrapper.mPendingCalls[this.mId] = this;
}

CCallWrapper.prototype.execute = function() {
  this.mObjectReference[this.mMethodName](this.mArgument0,this.mArgument1,this.mArgument2,this.mArgument3,this.mArgument4,this.mArgument5,this.mArgument6,this.mArgument7,this.mArgument8,this.mArgument9);
  delete CCallWrapper.mPendingCalls[this.mId];
};

CCallWrapper.prototype.cancel = function() {
  clearTimeout(this.mTimerId);
  delete CCallWrapper.mPendingCalls[this.mId];
};

CCallWrapper.asyncExecute = function (/* CCallWrapper */ callwrapper) {
  CCallWrapper.mPendingCalls[callwrapper.mId].mTimerId = setTimeout('CCallWrapper.mPendingCalls["' + callwrapper.mId + '"].execute()', callwrapper.mDelay);
};

CCallWrapper.mCounter = 0;
CCallWrapper.mPendingCalls = {};
