var DATA_SRC = "http://www.networkbench.com/trade-rank/";
var XML2JSON_URL = "http://dfeed.networkbench.com/xml2json/xml2json.js";
var CROSS_DOMAIN = (document.domain != "www.networkbench.com");
var REPORT_TYPE_WEEKLY = 1;
var REPORT_TYPE_MONTHLY = 2;
var REPORT_TYPE_QUARTERLY = 3;
var REPORT_TYPE_YEARLY = 4;
var TODAY = new Date();

var tradeList;
var curTradePerfReport = null;
var curTaskId = null;

function NBTradePerfReport(tradeId, reportType, reportYear, reportIndex) {
	this.tradeId = tradeId;
	this.reportType = reportType || REPORT_TYPE_WEEKLY;
	this.reportYear = reportYear;
	this.reportIndex = reportIndex;
	this.data = null;
	this.__loaded = false;

	var rptobj  = this;
	this.load = function(callback) {
		var reportPath = getReportPath(this.tradeId, this.reportType, this.reportYear, this.reportIndex);
		/*
		asyncRequest(reportPath, function(resp, req) {
			rptobj.data = xml2Obj(req.responseXML);
			if(callback) callback(rptobj);
		}, true);
		*/
		loadXml(reportPath, function(data) {
			rptobj.data = data;
			if(callback) callback(rptobj);
		}, true);
	};
}

function loadTradeList(callback) {
	//asyncRequest(DATA_SRC + "TradeList.xml", function(resp, req) {
	//	var data = xml2Obj(req.responseXML);
	loadXml(DATA_SRC + "TradeList.xml", function(data) {
		if(data != null) {
			tradeList = data.list.trade;
			if(tradeList == null) {
				tradeList = [];
			} else if(tradeList.slice == undefined) {
				//cast to array
				tradeList = [tradeList];
			}

			if(callback) callback();
		}
	}, true);
}

function loadTradePerfReport(tradeId, reportType, reportYear, reportIndex, callback) {
	var trade = null;
	if(reportType == undefined) {
		if(curTradePerfReport == null) {
			reportType = REPORT_TYPE_WEEKLY;
		} else {
			reportType = curTradePerfReport.reportType;
		}
	}
	for(var i = 0; i < tradeList.length; i++) {
		if(tradeList[i].id == tradeId) {
			trade = tradeList[i];
			break;
		}
	}
	
	if(curTradePerfReport == null || curTradePerfReport.tradeId != tradeId || curTradePerfReport.reportType != reportType || curTradePerfReport.reportYear != reportYear || curTradePerfReport.reportIndex != reportIndex) {
		//load the report
		curTradePerfReport = new NBTradePerfReport(tradeId, reportType, reportIndex);
	}

	if(!curTradePerfReport.__loaded) {
		curTradePerfReport.load(callback || function() {
			var daterangeobj = document.getElementById("reportDateRange");
			setInnerHTML(daterangeobj, curTradePerfReport.data == null || curTradePerfReport.data.report == null ? "" : (curTradePerfReport.data.report.startDate + " ~ " + curTradePerfReport.data.report.endDate).replace(/[-]/g,"."));
			//show trade & tasks list tree
			var tree = window["dtree"] = new dTree("dtree");			
			tree.config.useCookies = false;
			tree.add(0, -1, SEARCH_RESULTS);
			var seltask = null;
			var selTreeId = null;
			if(trade != null) {
				var ni = tree.aNodes.length;
				tree.add(ni++, 0, trade.name, "javascript:dtree.o(1)");
				var tasks = trade.task;
				if(tasks != null) {
					if(tasks.length) {
						for(var j = 0, selTreeId = ni; j < tasks.length; j++) {
							tree.add(ni++, 1, tasks[j].name, "javascript:showTaskPerf(" + tradeId + "," + tasks[j].id + ")");
						}
						seltask = tasks[0];
					} else {
						selTreeId = ni;
						tree.add(ni++, 1, tasks.name, "javascript:showTaskPerf(" + tradeId + "," + tasks.id + ")");
						seltask = tasks;
					}
				}
			}
			setInnerHTML(document.getElementById("treeResult"), tree.toString());
			tree.openAll();
			//show data for the selected task
			if(seltask != null) {
				showTaskPerf(tradeId, seltask.id);
				tree.s(selTreeId);
			} else {
				document.getElementById("details").style.display = "none";
			}
		});
	}
}

function loadTopTradePerfList(tradeIdList, reportType, callback) {
	var loadTopTradePerf = function(tradeId, reportType, callback) {
		new NBTradePerfReport(tradeId, reportType).load(function(tradeperfrpt) {
			if(callback) callback(tradeperfrpt);
		});
	};

	if(tradeIdList) {
		for(var i = 0; i < tradeIdList.length; i++) {
			loadTopTradePerf(tradeIdList[i], reportType, callback);
		}
	}
}

function showTaskPerf(tradeId, taskId) {
	var detailsobj1 = document.getElementById("details_1");
	var detailsobj3 = document.getElementById("details_3");
	if(taskId == null) {
		detailsobj1.style.display = "none";
		detailsobj3.style.display = "none";
		return;
	}
	var showTaskPerfInternal = function() {
		var rptdata = (curTradePerfReport.data == null ? null : curTradePerfReport.data.report);
		var taskType = (rptdata == null ? null : rptdata.taskType || 1);
		var tsUserIdx = (rptdata == null ? null : parseFloat(rptdata.idxUser));
		var tsTotalIdx = (rptdata == null ? null : parseFloat(rptdata.idxTotal));
		var bytesIdx = (rptdata == null ? null : parseFloat(rptdata.idxByteTotal));
		var elemIdx = (rptdata == null ? null : parseFloat(rptdata.idxElements));
		var rateDownloadIdx = (rptdata == null ? null : parseFloat(rptdata.idxRateDownload));
		var availIdx = (rptdata == null ? null : parseFloat(rptdata.idxAvail));
		
		var detailsobj;
		if(taskType == 3) {
			detailsobj = detailsobj3.firstChild;
		} else {
			detailsobj = detailsobj1.firstChild;
		}

		var tdTsUser = detailsobj.rows[1].cells[1];
		var tdTsTotal = detailsobj.rows[2].cells[1];
		var tdRateDownload = detailsobj.rows[3].cells[1];
		var tdAvail = detailsobj.rows[4].cells[1];
		var tdBytes = detailsobj.rows[5].cells[1];
		var tdElem = detailsobj.rows[6].cells[1];

		var taskrpts = (rptdata == null ? null : rptdata.data);
		if(taskrpts != null) {
			var taskrpt = null;
			if(taskrpts.length) {
				for(var i = 0; i < taskrpts.length; i++) {
					if(taskrpts[i].taskId == taskId) {
						taskrpt = taskrpts[i];
						break;
					}
				}
			} else if(taskrpts.taskId == taskId) {
				taskrpt = taskrpts;
			}

			if(taskrpt != null) {
				var tsUser = parseFloat(taskrpt.tsUser);
				var tsTotal = parseFloat(taskrpt.tsTotal);
				var bytes = parseFloat(taskrpt.byteTotal);
				var elem = parseFloat(taskrpt.elements);
				var rateDownload = parseFloat(taskrpt.rateDownload);
				var avail = parseFloat(taskrpt.available);
				
				tdTsUser.className = (tsUser > tsUserIdx ? "val_bad" : "val_good");
				tdTsTotal.className = (tsTotal > tsTotalIdx ? "val_bad" : "val_good");
				tdRateDownload.className = (rateDownload < rateDownloadIdx ? "val_bad" : "val_good");
				tdAvail.className = (avail < availIdx ? "val_bad" : "val_good");
				setInnerHTML(tdTsUser, formatNumber(tsUser/1000, "#.0"));
				setInnerHTML(tdTsTotal, formatNumber(tsTotal/1000, "#.0"));
				setInnerHTML(tdBytes, formatNumber(bytes/1024.0, "#.0"));
				setInnerHTML(tdElem, taskType == 3 ? formatNumber(elem + 1, "#.0") : formatNumber(elem, "#"));
				setInnerHTML(tdRateDownload, formatNumber(rateDownload/1024, "#.0"));
				setInnerHTML(tdAvail, formatNumber(avail, "#.0"));

				setInnerHTML(document.getElementById("siteNameContainer"), taskrpt.taskName);
				var siteurlcontainer = document.getElementById("siteUrlContainer");
				var taskurl = taskrpt.taskUrl;
				if(taskurl && taskurl.length > 64) {
					taskurl = taskurl.substring(0, 40) + "..." + taskurl.substring(taskurl.length - 21);
				}
				siteurlcontainer.href = taskrpt.taskUrl;
				setInnerHTML(siteurlcontainer, taskurl);
			} else {
				setInnerHTML(tdTsUser, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--");
				setInnerHTML(tdTsTotal, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--");
				setInnerHTML(tdBytes, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--");
				setInnerHTML(tdElem, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--");
				setInnerHTML(tdRateDownload, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--");
				setInnerHTML(tdAvail, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--");
				tdTsUser.className = tdTsTotal.className = tdRateDownload.className = tdAvail.className = "";
				var taskdef = null;				
				for(var i = 0; i < tradeList.length; i++) {
					if(tradeList[i].id == tradeId) {
						var tasks = tradeList[i].task;
						if(tasks != null) {
							if(tasks.length) {
								for(var j = 0; j < tasks.length; j++) {
									if(tasks[j].id == taskId) {
										taskdef = tasks[j];
										break;
									}											
								}
							} else {
								if(tasks.id == taskId) taskdef = tasks;
							}
						}
						break;
					}
				}
				
				var siteurlcontainer = document.getElementById("siteUrlContainer");
				if(taskdef != null) {
					setInnerHTML(document.getElementById("siteNameContainer"), taskdef.name);				
					var taskurl = taskdef.url;
					if(taskurl && taskurl.length > 64) {
						taskurl = taskurl.substring(0, 40) + "..." + taskurl.substring(taskurl.length - 21);
					}
					siteurlcontainer.href = taskdef.url;
					setInnerHTML(siteurlcontainer, taskurl);
				} else {
					setInnerHTML(document.getElementById("siteNameContainer"), "");
					siteurlcontainer.href = "#";
					setInnerHTML(siteurlcontainer, "");
				}
			}
		} else {
			setInnerHTML(tdTsUser, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--");
			setInnerHTML(tdTsTotal, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--");
			setInnerHTML(tdBytes, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--");
			setInnerHTML(tdElem, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--");
			setInnerHTML(tdRateDownload, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--");
			setInnerHTML(tdAvail, "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--");
			tdTsUser.className = tdTsTotal.className = tdRateDownload.className = tdAvail.className = "";
		}

		setInnerHTML(detailsobj.rows[1].cells[2], tsUserIdx == null ? "--" : formatNumber(tsUserIdx/1000, "#.0"));
		setInnerHTML(detailsobj.rows[2].cells[2], tsTotalIdx == null ? "--" : formatNumber(tsTotalIdx/1000, "#.0"));
		setInnerHTML(detailsobj.rows[3].cells[2], rateDownloadIdx == null ? "--" : formatNumber(rateDownloadIdx/1024, "#.0"));
		setInnerHTML(detailsobj.rows[4].cells[2], availIdx == null ? "--" : formatNumber(availIdx, "#.0"));
		setInnerHTML(detailsobj.rows[5].cells[2], bytesIdx == null ? "--" : formatNumber(bytesIdx/1024, "#.0"));
		setInnerHTML(detailsobj.rows[6].cells[2], elemIdx == null ? "--" : taskType == 3 ? formatNumber(elemIdx + 1, "#.0") : formatNumber(elemIdx, "#"));
		detailsobj.style.display = "";
		
		if(taskType == 3) {
			detailsobj1.style.display = "none";
			detailsobj3.style.display = "";
		} else {
			detailsobj3.style.display = "none";
			detailsobj1.style.display = "";
		}
	};

	if(curTradePerfReport == null || curTradePerfReport.tradeId != tradeId) {
		//load the report
		curTradePerfReport = new NBTradePerfReport(tradeId, curTradePerfReport == null ? REPORT_TYPE_WEEKLY : curTradePerfReport.reportType , 
															curTradePerfReport == null ? null : curTradePerfReport.reportYear, 
															curTradePerfReport == null ? null : curTradePerfReport.reportIndex);
		curTradePerfReport.load(function() {
			showTaskPerfInternal();
		});
	} else {
		showTaskPerfInternal();
	}
	curTaskId = taskId;
}

function switchReportType(reportType, obj) {
	if(curTradePerfReport != null) {
		loadTradePerfReport(curTradePerfReport.tradeId, reportType, curTradePerfReport.reportYear, curTradePerfReport.reportIndex, function() {
			var daterangeobj = document.getElementById("reportDateRange");
			setInnerHTML(daterangeobj, curTradePerfReport.data == null || curTradePerfReport.data.report == null ? "" : (curTradePerfReport.data.report.startDate + " ~ " + curTradePerfReport.data.report.endDate).replace(/[-]/g,"."));
			showTaskPerf(curTradePerfReport.tradeId, curTaskId);
		});
		var liobj = obj.parentNode;
		var ulobj = liobj.parentNode;
		var tmpobj = ulobj.firstChild;
		for(var tmpobj = ulobj.firstChild; tmpobj != null; tmpobj = tmpobj.nextSibling) {
			if(tmpobj.nodeType == 1 && tmpobj != liobj) tmpobj.firstChild.className = "";
		}
		liobj.firstChild.className = "select_date";
	}
}

function searchTradeTasks() {
	var keywd = document.getElementById("keyword").value;
	if(keywd != "" && (keywd = keywd.replace(/(^\s*)|(\s*$)/g, "")) != "") {
		keywd = keywd.toLowerCase();
		var matchedTask = null;
		//show trade & tasks list tree
		var tree = window["dtree"] = new dTree("dtree");		
		tree.config.useCookies = false;
		tree.add(0, -1, SEARCH_RESULTS);
		var ni = 1;

		var lastTrade = null;
		var lastTreeId = null;
		var selTreeId = null;

		for(var i = 0; i < tradeList.length; i++) {
			var tmptrade = tradeList[i];
			var tasks = tmptrade.task;
			if(tasks != null) {
				if(tasks.length) {
					for(var j = 0; j < tasks.length; j++) {
						var tmptask = tasks[j];
						if((tmptask.name && tmptask.name.toLowerCase().indexOf(keywd)) != -1 || (tmptask.url && tmptask.url.toLowerCase().indexOf(keywd) != -1)) {
							//matches							
							if(tmptask.trade == undefined) tmptask.trade = tmptrade;
							if(tmptrade != lastTrade) {
								tree.add(lastTreeId = ni, 0, tmptrade.name, "javascript:dtree.o(" + (ni++) + ")");
							}
							if(matchedTask == null) {
								matchedTask = tmptask;
								selTreeId = ni;
							}
							tree.add(ni++, lastTreeId, tmptask.name, "javascript:showTaskPerf(" + tmptrade.id + "," + tmptask.id + ")");
							lastTrade = tmptrade;
						}
					}
				} else {
					if((tasks.name && tasks.name.toLowerCase().indexOf(keywd) != -1) || (tasks.url && tasks.url.toLowerCase().indexOf(keywd) != -1)) {
						//matches
						if(tasks.trade == undefined) tasks.trade = tmptrade;
						if(tmptrade != lastTrade) {
							tree.add(lastTreeId = ni, 0, tmptrade.name, "javascript:dtree.o(" + (ni++) + ")");
						}
						if(matchedTask == null) {
							matchedTask = tasks;
							selTreeId = ni;
						}
						tree.add(ni++, lastTreeId, tasks.name, "javascript:showTaskPerf(" + tmptrade.id + "," + tasks.id + ")");
						lastTrade = tmptrade;	
					}
				}
			}
		}

		setInnerHTML(document.getElementById("treeResult"), tree.toString());
		tree.openAll();
		//show data for the selected task
		if(matchedTask) {
			showTaskPerf(matchedTask.trade.id, matchedTask.id);
			tree.s(selTreeId);
		} else {
			document.getElementById("details").style.display = "none";
		}
	}
}

function getFirstWeekDay(currDate){ 
    var calcDate;
    for (var i=0;i<7;i++){
        calcDate=new Date(currDate.getFullYear(),0,i+1);
        if (calcDate.getDay()==0){
           break;
        }
    }
    return calcDate;
}
function ifLastYear(currDate){
    if (currDate.getMonth()==0){
        var firstDate = getFirstWeekDay(currDate);
        if (currDate < firstDate)
            return true;
    }else{
        return false;
    }
}
Date.prototype.getWeek = function(firstDate) {
    var onejan = firstDate;
    return Math.ceil((Math.floor((this - onejan) / 86400000) + onejan.getDay()+1)/7);
}

function getReportPath(tradeId, reportType, reportYear, reportIndex){
	if(reportYear == undefined || reportYear <= 0) {
		//set default value for today
		switch(reportType) {
			case REPORT_TYPE_WEEKLY :
				var weekDay = new Date();
				weekDay.setTime(TODAY.getTime() - 604800000 * 4/*1000*60*60*24*7*/);
				var firstDate;
				if(ifLastYear(weekDay)){
					weekDay = new Date(weekDay.getFullYear() - 1 , 11, 31);
				}
				reportYear = weekDay.getFullYear();
				reportIndex = weekDay.getWeek(getFirstWeekDay(weekDay));
				break;
			case REPORT_TYPE_MONTHLY :
				reportYear = TODAY.getFullYear();
				reportIndex = TODAY.getMonth();
				if(reportIndex == 0) {
					reportYear--;
					reportIndex = 12;
				}
				break;
			case REPORT_TYPE_QUARTERLY :
				reportYear = TODAY.getFullYear();
				var month = TODAY.getMonth();
				if(month < 3) {
					reportYear--;
					reportIndex = 4;
				} else if(month < 6) {
					reportIndex = 1;
				} else if(month < 9) {
					reportIndex = 2;
				} else {
					reportIndex = 3;
				}
				break;
			case REPORT_TYPE_YEARLY :
				reportYear = TODAY.getFullYear() - 1;
				reportIndex = 0;
				break;
		}
	}

	return DATA_SRC + reportYear + "/" + tradeId + "/" + tradeId + reportYear + reportType + (reportIndex < 10 ? "0" + reportIndex : reportIndex) + ".xml";
}

function getXmlHttpPrefix() {
	if (getXmlHttpPrefix.prefix)
		return getXmlHttpPrefix.prefix;
	
	var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
	var o;
	for (var i = 0; i < prefixes.length; i++) {
		try {
			// try to create the objects
			o = new ActiveXObject(prefixes[i] + ".XmlHttp");
			return getXmlHttpPrefix.prefix = prefixes[i];
		}
		catch (ex) {};
	}
	
	throw new Error("Could not find an installed XML parser");
}

// XmlHttp factory
function XmlHttp() {}

XmlHttp.create = function () {
	try {
		if (window.XMLHttpRequest) {
			var req = new XMLHttpRequest();
			
			// some versions of Moz do not support the readyState property
			// and the onreadystate event so we patch it!
			if (req.readyState == null) {
				req.readyState = 1;
				req.addEventListener("load", function () {
					req.readyState = 4;
					if (typeof req.onreadystatechange == "function")
						req.onreadystatechange();
				}, false);
			}
			
			return req;
		}
		if (window.ActiveXObject) {
			return new ActiveXObject(getXmlHttpPrefix() + ".XmlHttp");
		}
	}
	catch (ex) {}
	// fell through
	throw new Error("Your browser does not support XmlHttp objects");
};

function asyncRequest(url, callback, nocache) {
	var req = XmlHttp.create();
	
	if(nocache) {
		//req.setRequestHeader("Pragma", "no-cache");
		//req.setRequestHeader("Cache-Control", "no-cache, must-revalidate");
		url += (url.indexOf("?") == -1 ? "?rnd=" : "&rnd=") + Math.random();
	}

	req.open("GET", url, true);
	req.onreadystatechange = function()
	{

		if (req.readyState == 4)
		{
			if(callback) {
				var resp = req.responseText;
				callback(resp, req);
			}
		}
	}

	req.send(null);
}

var XML2JSON_CALLBACK_COUNT = 0;
function loadXml(url, callback, nocache) {
	if(CROSS_DOMAIN) {
		var sxobj = document.createElement("script");
		sxobj.type="text/javascript";
		var charset = window["DOCUMENT_CHARSET"] || document.charset || document.characterSet || "UTF-8";
		if(charset.indexOf("x-") == 0 || charset.indexOf("X-") == 0) charset = charset.substring(2);
		var xml2jsonProxy = XML2JSON_URL + "?src=" + encodeURIComponent(url) + "&xmlencoding=UTF-8&jsonencoding=" + charset;
		if(callback) {
			var callbackName;
			var regexfn = /^\s*function\s*([a-zA-Z0-9_$]+)\s*.*/;
			if(regexfn.test(callback.toString())) {
				callbackName = RegExp.$1;
			} else {
				callbackName = "XML2JSON_CALLBACK_" + (++XML2JSON_CALLBACK_COUNT);
				window[callbackName] = callback;
			}
			xml2jsonProxy += "&callback=" + callbackName;
		}
		sxobj.src = xml2jsonProxy;
		document.getElementsByTagName("HEAD")[0].appendChild(sxobj);		
	} else {
		asyncRequest(url, function(resp, req) {
			var jsonObj = xml2Obj(req.responseXML);
			if(callback) callback(jsonObj);
		}, nocache);
	}
}

var NODE_TYPE_ELEMENT = 1;
var NODE_TYPE_ATTRIBUTE = 2;
var NODE_TYPE_TEXT = 3;
var NODE_TYPE_COMMENT = 8;

function xml2Obj(doc) {
	if(doc == null) return null;
	var obj = {};
	var rootObj = {};
	var docRoot = doc.documentElement;
	if(docRoot == null) return obj;
	xmlNode2Obj(docRoot, rootObj);
	obj[docRoot.nodeName] = rootObj;
	return obj;
}

function xmlNode2Obj(node, obj, parentObj) {
	switch(node.nodeType) {
		case NODE_TYPE_ELEMENT :
			var attribs = node.attributes;
			if(attribs != null) {
				for(var ai = 0; ai < attribs.length; ai++) {
					obj[attribs[i].nodeName] = attribs[i].nodeValue;
				}
			}
			var cnodes = node.childNodes;
			if(cnodes != null) {
				if(cnodes.length == 1 && cnodes[0].nodeType == NODE_TYPE_TEXT) {
					//has single text node, just return the text
					parentObj[node.nodeName] = cnodes[0].nodeValue;
				} else {
					var hasElementNode  = false;
					for(var ci = 0; ci < cnodes.length; ci++) {
						if(cnodes[ci].nodeType == NODE_TYPE_ELEMENT) {
							//clear text property if the node has child elements
							obj.innerText = null;
							hasElementNode = true;
							var ename = cnodes[ci].nodeName;
							var cobj = obj[ename];
							if(cobj != null) {
								if(cobj.slice != undefined) {
									//is an array
									var cobj2 = {};
									cobj[cobj.length] = cobj2;
									cobj = cobj2;
								} else {
									var cobj2 = {};
									var cobjs = [cobj, cobj2];
									obj[ename] = cobjs;
									cobj = cobj2;
								}
							} else {
								obj[ename] = cobj = {};
							}
							xmlNode2Obj(cnodes[ci], cobj, obj);
						} else if(cnodes[ci].nodeType == NODE_TYPE_TEXT) {
							if(!hasElementNode) {
								xmlNode2Obj(cnodes[ci], cnodes[ci].nodeValue, obj);
							}
						}
					}
				}
			}
			break;
		case NODE_TYPE_TEXT :
			parentObj.innerText = obj;
			break;
		case NODE_TYPE_ATTRIBUTE :
		case NODE_TYPE_COMMENT :
			break;
	}
}

function setInnerHTML(element, str) {
	if(navigator.appName.indexOf("Microsoft Internet Explorer") ==  -1) {
		var r = element.ownerDocument.createRange();
		r.selectNodeContents(element);
		r.deleteContents();
		var df = r.createContextualFragment(str);
		element.appendChild(df);
		
		return str;	
	} else {	
		element.innerHTML = str;
		return str;
	}
}

function formatNumber(num, fmt) {
	if(num == undefined) return null;
	if(fmt == undefined || fmt == "") return num.toFixed(2);
	var precision;
	var dotIndex = fmt.indexOf(".");
	if(dotIndex == -1) {
		precision = 0;
	} else {
		precision = fmt.length - dotIndex - 1;
	}

	return num.toFixed(precision);
}
