window.commandQueue = new CommandQueue();

function XmlCreator(data){this.data=data;}
XmlCreator.prototype.create=function()
{
  return '<?xml version="1.0" encoding="UTF-8"?>'+this.extractElements(this.data);
}
XmlCreator.prototype.createElement=function(name){return }
XmlCreator.prototype.extractAttributes=function(data)
{
  var result="";
  for(var name in data)
  {
    if(this.isAttribute(data[name])){result+=" "+name+"='"+data[name]+"'";}
  }
  return result;
}
XmlCreator.prototype.extractElement=function(name,data)
{
  var result="<"+name+this.extractAttributes(data);
  var children=this.extractElements(data);
  if(children.length>0){result+=">"+children+"</"+name+">";}else{result+=" />";}  
  return result;
}
XmlCreator.prototype.extractElements=function(data)
{
  var result="";
  for(var name in data)
  {
    if(!this.isAttribute(data[name]))
    {
      if(!this.isArray(data[name])){result+=this.extractElement(name,data[name]);}
      else{result+=this.extractElementsFromArray(name,data[name]);}
    }
  }
  return result;
}
XmlCreator.prototype.extractElementsFromArray=function(name,data)
{
  var result="";
  for(var i=0;i<data.length;i++){result+=this.extractElement(name,data[i]);}
  return result;
}
XmlCreator.prototype.isArray=function(object){return object.push!=undefined;}
XmlCreator.prototype.isAttribute=function(object){return object.replace!=undefined||object.toFixed!=undefined;}


function Command(name,handler,context)
{
  this.verb="GET";
  this.name=name;
  this.handler=handler;
  this.handlerContext=context;
  this.parameters=new Array();
  this.parameters.push("svc");
  this.parameters.push(name);
  this.dialog=null;
  this.data=null;
  this.cancelled=false;
  this.hasDefaultDialog=false;
}
Command.prototype.addParameter=function(value){this.parameters.push(value);}
Command.prototype.getData=function(){return this.data.create();}
Command.prototype.hasData=function(){return this.data!=null;}
Command.prototype.setData=function(data){this.data=new XmlCreator(data);this.verb="POST";}
Command.prototype.showStatusDialog=function(title,msg)
{
  this.dialog=new Dlg(title,"statusDlg",250,100);
  this.dialog.hasStatusBar=true;
  this.dialog.msg=msg;
  this.hasDefaultDialog=true;
}

function CommandQueue()
{
  this.currentXmlHttp=null;
  this.currentCommand=null;
  this.commands=new Array();
  this.isExecuting=false;
  this.isAdding=false;
}
CommandQueue.prototype.add=function(cmd)
{
  this.isAdding=true;
  this.commands.push(cmd);
  this.executeNext();
  this.isAdding=false;
}
CommandQueue.prototype.cancel=function(name)
{
  for(var cmd in this.commands)
  {
    if(cmd.name==name)
    {
      var failed=false;
      for(var i=1;i<arguments.length;i++)
      {
        if(i+1<cmd.parameters.length&&arguments[i]!=cmd.parameters[i+1]){failed=true;}
      }
      if(!failed){cmd.cancelled=true;return;}
    }
  }
}
CommandQueue.prototype.executeNext=function()
{
  if(this.commands.length==0)return;
  if(this.isExecuting)return;
  this.isExecuting=true;
  
  var command=this.commands.shift();
  while(this.commands.length>0&&command.cancelled){command=this.commands.shift();}
  if(command.cancelled){this.isExecuting=false;return;}
  
  this.currentCommand=command;
  
  if(command.dialog!=null){command.dialog.show();}
  
  this.currentXmlHttp=getXmlHttp();
  if(!this.currentXmlHttp){alert("We are unable to process your request.");}
  this.currentXmlHttp.open(command.verb,buildUrl.apply(window,command.parameters),true);
  
  this.currentXmlHttp.onreadystatechange = function()
  {
    if(window.commandQueue.currentXmlHttp!=undefined&&window.commandQueue.currentXmlHttp.readyState==4)
    {
      var cmd=window.commandQueue.currentCommand;
      
      var result=null;
      try
      {
        result=eval('('+window.commandQueue.currentXmlHttp.responseText+')').result;
      }
      catch(e)
      {
        if(cmd.dialog!=null)
        {
          cmd.dialog.clrSbar();
          cmd.dialog.setMsg("<p>Processing failed.</p><p>Please refresh this page and try again.</p>");
        }
        return;
      }
      
      if(cmd.hasDefaultDialog)cmd.dialog.hide();
      
      if(cmd.handler!=null)
      {
        if(cmd.handlerContext!=null){cmd.handler.call(cmd.handlerContext,result,cmd.dialog);}
        else{command.handler(result,cmd.dialog);}
      }
      window.commandQueue.currentXmlHttp=null;
      window.commandQueue.checkNext();
    }
  };
  if(command.hasData()){this.currentXmlHttp.send(command.getData());}else{this.currentXmlHttp.send(null);}
}
CommandQueue.prototype.checkNext=function()
{
  if(window.commandQueue.isAdding)
  {
    setTimeout(window.commandQueue.checkNext,10);
    return;
  }
  window.commandQueue.isExecuting=false;
  window.commandQueue.executeNext();
}
CommandQueue.prototype.isBusy=function(){return this.isExecuting||this.isAdding;}
function buildUrl(type,cmd)
{
  var rslt=new Array();
  rslt.push(window.location.protocol);
  rslt.push("");
  rslt.push(window.location.hostname);
  if(getUrlSessionId()!=null)rslt.push(getUrlSessionId());
  if(type.length>0)rslt.push(type);
  for(var i=2;i<arguments.length;i++){rslt.push(encodeURI(arguments[i]));}
  rslt.push(cmd+".aspx");
  return rslt.join("/");
}
function getXmlHttp()
{
  var creator=function() {return new ActiveXObject('Msxml2.XMLHTTP')};
  var result;
  try{result=creator();}
  catch(e)
  {
    creator=function() {return new ActiveXObject('Microsoft.XMLHTTP')};
    try{result=creator();}
    catch(e)
    {
      creator=function() {return new XMLHttpRequest()};
      try{result=creator();}
      catch(e){result=false;}
    }
  }
  return result;
}
function getUrlSessionId(){return document.URL.match(/[\dabcdef]{8}-[\dabcdef]{4}-[\dabcdef]{4}-[\dabcdef]{4}-[\dabcdef]{12}/);}
function getSessionId()
{
  var rslt=getUrlSessionId();
  if (rslt==null)
  {
    var cookies=document.cookie;
    var start=cookies.indexOf("ses=")+4;
    if(start!=3)
    {
      var end=cookies.indexOf(";", start);
      if(end==-1)end=cookies.length;
      rslt=unescape(cookies.substring(start,end));
    }
  }
  return rslt;
}
function xmlEncode(value)
{
  var result=new Array()
  for(var i=0;i<value.length;i++)
  {
    result.push(value.charCodeAt(i));
  }
  return "%"+result.join("%");
}