
// CLASS ZangClient : Encapsulates zangerland client-server communications
function ZangClient(zangServerUrl){
 this.zangServerScriptName=zangServerUrl;
 this.lastMessageTime=0;
 this.callbacks=new Array();
 this.xhr=createXMLHttpRequest();
 this.processingCommand=false;
 this.commandQueue=new Array();
 var self=this;
 setEventHandler(window,'load',function(){self.initialize()});
}

ZangClient.prototype={

// METHOD ZangClient.initialize : Execute initialization code on window.onload
 initialize:function(){
  this.createMessageReciever();
  this.startMessageReciever();
 },

// METHOD ZangClient.createMessageReciever : Create iframe/httprequest to recieve data from message pusher
 createMessageReciever:function(){
  var bodyDom=document.getElementsByTagName("body").item(0);
  var zangPusherDiv=document.createElement("div");
  bodyDom.appendChild(zangPusherDiv);
  zangPusherDiv.innerHTML='<iframe id="zangPusher" style="width:0;height:0;border:none;"></iframe>';
  var zangPusherDom=document.getElementById("zangPusher");
  this.zangPusherDom=zangPusherDom;
//  var self=this;
//  setEventHandler(zangPusherDom,'load',function(){self.refreshMessageReciever()});
 },

// METHOD ZangClient.refreshMessageReciever : reloads pushed message stream
// refreshMessageReciever:function(){
//  if(this.zangPusherDom.getAttribute('src')){
//   this.zangPusherDom.setAttribute('src',this.zangPusherDom.getAttribute('src'));
//  }
// },

// METHOD ZangClient.startMessageReciever : start loading message reciever iframe
 startMessageReciever:function(){
  if(!document.recieveMsg){
   var self=this;
   document.recieveMsg=function(message){self.recieveMessage(message)};
  }
  this.zangPusherDom.setAttribute('src',this.zangServerScriptName+"?command=startserverpusher&lastmessagetime="+this.lastMessageTime);
 },

// METHOD ZangClient.sendCommandToServer : Sends a command to the server
 sendCommandToServer:function(command){
  if(this.processingCommand){
   this.commandQueue.push(command);
   if(this.commandQueue.length==0){
    var logDom=document.getElementById('cmdqueue');
    logDom.innerHTML='';
   }else writeToWindow('cmdqueue','systemerror',this.commandQueue.join('; '));
  }else{
   this.processingCommand=true;
   url=this.zangServerScriptName+"?command="+command;
   url+="&lastmessagetime="+this.lastMessageTime;
   this.xhr.open("GET",url);
   var self=this;
   this.xhr.onreadystatechange=function(){self.processServerMessage()}
   this.xhr.setRequestHeader("If-Modified-Since","Sat, 1 Jan 2000 00:00:00 GMT");
   this.xhr.send(null);
  }
 },

// METHOD ZangClient.processServerMessage : Processes replies from server
 processServerMessage:function(){
  if(this.xhr.readyState==4){
   this.processingCommand=false;
   try{
    var responseList=eval('('+this.xhr.responseText+')');
    if(responseList.length!=0)this.recieveMessage(responseList);
    if(this.commandQueue.length>0){
     this.sendCommandToServer(this.commandQueue.shift());
     if(this.commandQueue.length==0){
      var logDom=document.getElementById('cmdqueue');
      logDom.innerHTML='';
     }else writeToWindow('cmdqueue','systemerror',this.commandQueue.join('; '));
    }
   }catch(e){
    writeToWindow('log','systemerror','Problem with response: "'+this.xhr.responseText+'"');
   }
  }
 },

// METHOD ZangClient.registerEventListener : Add a new event listener that gets notified about server messages
 registerEventListener:function(message_type,callbackFunction){
  this.callbacks[message_type]=callbackFunction;
 },

// METHOD ZangClient.recieveMessage : gets called for every message recieved to adjust gui
 recieveMessage:function(response){
  if(!response.length)response[0]=response;
  for(var i=0;i<response.length;i++){
   var message=response[i];
   this.lastMessageTime=message['msgtime'];
   try{
    switch(message.message_type){
    case "done":this.startMessageReciever();break;
    case "receipt":break;
    default:
     if(this.callbacks['timetic'])this.callbacks['timetic'](message)
     if(this.callbacks[message.message_type]){
      this.callbacks[message.message_type](message)
     }else{
      writeToWindow('log','systemerror','no callback defined for: message_type('+message.message_type+'), errorcode('+message.errorcode+'), errortext('+message.errortext+')');
     }
    }
   }catch(e){writeToWindow('log','systemerror','Problem processing response: '+response+' : '+e);}
  }
 }

}