var rt = new XWTRuntime(); 

function XWTRuntime() {
    // WATCH LEVEL
    var xwtLogger = new XWTLogger();
    this.LOGLEVEL_INFO = xwtLogger.INFO;
    this.LOGLEVEL_DEBUG = xwtLogger.DEBUG;
    this.LOGLEVEL_WARN = xwtLogger.WARN;
    this.LOGLEVEL_ERROR = xwtLogger.ERROR;
    this.LOGLEVEL_FATAL = xwtLogger.FATAL;
    //
    var consoleMap, defaultLogger, standalone;
    this.consoleMap = new HashMap();
    this.defaultLogger = null;
    this.standalone = false;
    this.createConsole = function(spanId, name) {
        var logger = null;
        if(document.getElementById(spanId)) {
            logger = new XWTLogger(spanId);
        }
        if(logger!=null) {
            if(!name) {
                logger.setWatch(this.LOGLEVEL_DEBUG, false);
                this.consoleMap.put('DEFAULT', logger);
                this.defaultLogger = logger;
            } else {
                this.consoleMap.put(name, logger);
            }
        }
    }
    this.log = function(msg, consoleName, level) {
        var logger=null;
        if(consoleName) {
            logger = this.consoleMap.get(consoleName);
        } else {
            logger = this.defaultLogger;
        }
        if(logger) {
            if(level) {
                logger.log(level, msg);
            } else {
                logger.log(this.LOGLEVEL_DEBUG, msg);
            }
        }
    }
    this.isStandalone = function() {
        return this.standalone;
    }
    this.setStandalone = function(standalone) {
        if(standalone!=null) {
            if(standalone) {
                this.standalone = true;
            } else {
                this.standalone = false;
            }
        } else {
            this.standalone = false;
        }
    }
}

function XWTUtil() {
    this.getTimestamp = function(pattern) {
        var s = pattern;
        var year, month, date, hour, min, sec;
        var now = new Date();
        year = now.getYear()+1900;
        month = now.getMonth()+1;
        if(month<10) month='0'+month;
        date = now.getDate();
        if(date<10) date='0'+date;
        hour = now.getHours();
        hour2 = hour;
        if(hour<10) hour='0'+hour;
        if(hour2>12) hour2-=12;
        if(hour2<10) hour2='0'+hour2;
        min = now.getMinutes();
        if(min<10) min='0'+min;
        sec = now.getSeconds();
        if(sec<100) {
            if(sec<10) {
                sec = '00'+sec;
            } else {
                sec = '0'+sec;
            }
        }
        s = s.replace(/yyyy/g, year);
        s = s.replace(/MM/g, month);
        s = s.replace(/dd/g, date);
        s = s.replace(/HH/g, hour);
        s = s.replace(/hh/g, hour2);
        s = s.replace(/mm/g, min);
        s = s.replace(/sss/g, sec);
        return s;
    }
}

function XWTLogger(spanId) {
    // WATCH LEVEL
    this.INFO = 1;
    this.DEBUG = 2;
    this.WARN = 3;
    this.ERROR = 4;
    this.FATAL = 5;
    //
    var spanId, pattern, timestamp, watch, isExclusive, isOn;
    this.spanId = spanId;
    this.watch = this.INFO;
    this.isExclusive = false;
    this.isOn = true;
    this.pattern = '{TIMESTAMP} {LEVEL} {MESSAGE}';
    this.timestamp = 'yyyy/MM/dd HH:mm:sss';
    this.setPattern = function(pattern) {
        this.pattern = pattern;
    }
    this.setTimestamp = function(timestamp) {
        this.timestamp = timestamp;
    }
    this.setWatch = function(level, isExclusive) {
        this.watch = level;
        if(isExclusive) {
            this.isExclusive = isExclusive;
        } else {
            this.isExclusive = false;
        }
    }
    this.log = function(level, msg) {
        if( ((this.watch>=level && !this.isExclusive) || (this.watch==level && this.isExclusive))
            && this.isOn
            && document.getElementById(this.spanId) ) {
            document.getElementById(this.spanId).innerHTML += this.format(level, msg);
        }
    }
    this.format = function(level, msg) {
        var s = '<PRE>'+this.pattern+'</PRE>';
        var tagLevel = '';
        msg = msg.replace(/</g, '&lt;');
        msg = msg.replace(/>/g, '&gt;');
        switch(level) {
            case this.INFO: tagLevel='INFO'; break;
            case this.DEBUG: tagLevel='DEBUG'; break;
            case this.WARN: tagLevel='WARN'; break;
            case this.ERROR: tagLevel='ERROR'; break;
            case this.FATAL: tagLevel='FATAL'; break;
        }
        s = s.replace('{TIMESTAMP}', new XWTUtil().getTimestamp(this.timestamp));
        s = s.replace('{LEVEL}', tagLevel);
        s = s.replace('{MESSAGE}', msg);
        return s;
    }
    this.setOnOff = function(isOn) {
        if(isOn!=null) {
            if(isOn) {
                this.isOn = isOn;
            } else {
                this.isOn = false;
            }
       }
    }
}

function XWTObject(objId) {
    this.eventHandler = null;
    this.callbackHandler = null;
    this.params = new HashMap();

    this.setParameter = function(name, value) {
        this.params.put(encodeURIComponent(name), encodeURIComponent(value));
    }

    this.getParameter = function(name) {
        return this.params.get(name);
    }
    
    this.clear = function() {
    	this.params.clear();
    }

    this.newXMLRequest = function() {
      var xmlreq = false;
      if (window.XMLHttpRequest) {
	xmlreq = new XMLHttpRequest();
      } else if (window.ActiveXObject) {
	try {
	  xmlreq = new ActiveXObject("Msxml2.XMLHTTP");
	} catch (e1) {
	  try {
	    xmlreq = new ActiveXObject("Microsoft.XMLHTTP");
	  } catch (e2) {
	    xmlreq = false;
	  }
	}
      }
      return xmlreq;
    }

	//XML Object
    this.getXMLHandler = function(req, responseXmlHandler) {
       return function () {
       	  try {
			 // If the request's status is "complete"
			 if (req.readyState == 4) {
			   // Check that we received a successful response from the server
			   if (req.status && req.status == 200) {
			     // Pass the XML payload of the response to the handler function.
			     responseXmlHandler(req.responseXML);
			   } else {
			     // An HTTP problem has occurred
			     //alert("HTTP Error "+req.status+": "+req.statusText);
			   }
			 }
		  } catch (e1) {
		  }
       }
    }
    
    //Object
    this.getSendHandler = function(req, responseHandler) {
       return function () {
       	  try {
			 // If the request's status is "complete"
			 if (req.readyState == 4) {
			   // Check that we received a successful response from the server
			   if (req.status && req.status == 200) {
			     // Pass the XML payload of the response to the handler function.
			     responseHandler(req);
			   } else {
			     // An HTTP problem has occurred
			     //alert("HTTP Error "+req.status+": "+req.statusText);
			   }
			 }
		  } catch (e1) {
		  }
       }
    }

	//return xml Object
    this.submit = function(url) {
		var req = this.newXMLRequest();
		if(req) {
	            if(!rt.isStandalone()) {
	                req.onreadystatechange = this.getXMLHandler(req, this.callbackHandler.callback);
	                req.open('POST', url, true);
	                req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
	                var query = this.getQuery(this);
	                req.send(query);
	                if (this.callbackHandler.ontimeout) {
	                	var defaultTimeout = 5000;
	                	if (this.callbackHandler.timeout) {
	                		defaultTimeout = this.callbackHandler.timeout;
	                	}
	                	var timeoutFunction = this.callbackHandler.ontimeout;
		                var timeoutId = window.setTimeout(
		                	function() {
		                		if (callInProgress(req)) {
		                			req.abort();
		                			timeoutFunction(req);
		                		}
		                	}, defaultTimeout);
		            }
	            } else {
	                var query = this.getQuery(this);
	                rt.log('query='+query);
		    }
		}
    }
    
    //return Object
    this.send = function(url) {
		var req = this.newXMLRequest();
		if(req) {
	            if(!rt.isStandalone()) {
	                req.onreadystatechange = this.getSendHandler(req, this.callbackHandler.callback);
	                req.open('POST', url, true);
	                req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
	                var query = this.getQuery(this);
	                req.send(query);
	                if (this.callbackHandler.ontimeout) {
	                	var defaultTimeout = 5000;
	                	if (this.callbackHandler.timeout) {
	                		defaultTimeout = this.callbackHandler.timeout;
	                	}
	                	var timeoutFunction = this.callbackHandler.ontimeout;
		                var timeoutId = window.setTimeout(
		                	function() {
		                		if (callInProgress(req)) {
		                			req.abort();
		                			timeoutFunction(req);
		                		}
		                	}, defaultTimeout);
		            }
	            } else {
	                var query = this.getQuery(this);
	                rt.log('query='+query);
		    }
		}
    }

    this.getQuery = function(obj) {
		var s = '';
		for(var i=0;i<obj.params.size();i++) {
			if(s!='') s += '&';
			s += 'ajax_param'+i+'='+obj.params.getKeyByIndex(i);
			s += '&';
			s += 'ajax_value'+i+'='+obj.params.getValueByIndex(i);
		}
		
		//query.innerHTML = s;
		
		return s;
    }

    this.getEventHandler = function() {
        return this.eventHandler;
    }

    this.setEventHandler = function(handler) {
        this.eventHandler = handler;
    }

    this.getCallbackHandler = function() {
        return this.callbackHandler;
    }

    this.setCallbackHandler = function(handler) {
        this.callbackHandler = handler;
    }
	
	function callInProgress(xmlhttp) {
		switch (xmlhttp.readyState) {
			case 1:
			case 2:
			case 3:
				return true;
			default:
				return false;
		}
	}
}

function XWTEventHandler() {
    this.handleEvent = function() {
        alert('XWTEventHandler.handleEvent()');
    }
}

function XWTCallbackHandler() {
    this.callback = function(reqResponseXML) {
        alert('XWTCallbackHandler.callback()');
    }
}