// twobirds AJAX lib V 2.1.0 Author: 2002- Frank Thuerigen / phpbuero.de

// namespace for lib, DO NOT CHANGE
var tb = function() {
 return {};
 }();

tb.timer = {
 destroylist: [],
 addlist: [],
 list: [],
 ms: 100,

 // public

 add: function( pCallback, pTimeMs ) {
  var myDate = new Date();
  var myIdentifier = '_to'+tb.misc.getid();
  var myTime = myDate.getTime() + pTimeMs;
  var myArray = [ myTime, '( '+pCallback+' )', myIdentifier ];
  tb.timer.addlist.push( myArray );
  if (tb.timer.list.length === 0 ) {
   window.setTimeout( 'tb.timer.timeout()', 10);
   }
  return myIdentifier;
  },
  
 abort: function( pIdentifier ) {
  tb.timer.destroylist.push( pIdentifier );
  },

 //private

 destroy: function( pIdentifier ) {
  var myNewlist = [];
  var i=0;
  for ( i in tb.timer.list ) {
   if ( tb.timer.list[i][2] !== pIdentifier ) {
    var myObj = tb.misc.cloneObj( tb.timer.list[i] );
    myNewlist.push( myObj ); 
    }
   }
  tb.timer.list = myNewlist;
  },
  
 timeout: function() {
  while ( tb.timer.addlist.length > 0 ) {
   tb.timer.list.push( tb.timer.addlist.pop() );
   }
  while ( tb.timer.destroylist.length > 0 ) {
   tb.timer.destroy( tb.timer.destroylist.pop() );
   }
  if ( tb.timer.list.length < 1 ) {
   tb.timer.ms = 100;
   return;
   }
  else {
   var myNewList = [];
   var myMinVal = 0;
   while ( tb.timer.list.length > 0 ) {
    var myDate = new Date();
    var myTime = myDate.getTime();
    if ( tb.timer.list[0][0] <= myTime ) {
     var myEval = tb.timer.list[0][1];
     eval( '( ' + myEval + ' )' );
     }
    else {
     if ( tb.timer.list[0][1] < myMinVal || myMinVal === 0 ) {
      myMinVal = tb.timer.list[0][1];
      }
     myNewList.push( tb.timer.list[0] );
     }
    tb.timer.list.shift();
    }
   tb.timer.list = myNewList;
   if ( myMinVal > 0 ) {
    myDate = new Date();
    tb.timer.ms = myMinVal - myDate.getTime();
    }
   else {
    tb.timer.ms = 100;
    }
   while ( tb.timer.addlist.length > 0 ) {
    tb.timer.list.push( tb.timer.addlist.pop() );
    }
   window.setTimeout( 'tb.timer.timeout()', tb.timer.ms);
   } 
  }

 };
window.setTimeout( 'tb.timer.timeout()', 0);

tb.interval = {
 destroylist: [],
 addlist: [],
 list: [],
 ms: 100,
 
 // public
 
 add: function( pCallback, pTimeMs ) {
  var myDate = new Date();
  var myTime = myDate.getTime() + pTimeMs;
  var myIdentifier = '_itv'+tb.misc.getid();
  var myArray = [ myTime, pTimeMs, myIdentifier, '( '+pCallback+' )' ];
  tb.interval.addlist.push( myArray );
  if (tb.interval.list.length === 0 ) {
   tb.timer.add( 'tb.interval.timeout()', 10);
   }
  return myIdentifier;
  },
  
 abort: function( pIdentifier ) {
  tb.interval.destroylist.push( pIdentifier );
  },

 // private
 
 timeout: function() {
  while ( tb.interval.addlist.length > 0 ) {
   tb.interval.list.push( tb.interval.addlist.pop() );
   }
  while ( tb.interval.destroylist.length > 0 ) {
   tb.interval.destroy( tb.interval.destroylist.pop() );
   }
  if ( tb.interval.list.length < 1 ) {
   tb.interval.ms = 100;
   return;
   }
  else {
   var myNewList = [];
   var myMinVal = 0;
   while ( tb.interval.list.length > 0 ) {
    var myDate = new Date();
    var myTime = myDate.getTime();
    if ( tb.interval.list[0][0] <= myTime ) {
     var myEval = tb.interval.list[0][3];
     eval( '( ' + myEval + ' )' );
     myDate = new Date();
     myTime = myDate.getTime();
     tb.interval.list[0][0] = myTime + tb.interval.list[0][1];
     }
    if ( myMinVal === 0 || tb.interval.list[0][0] < myMinVal  ) {
     myMinVal = tb.interval.list[0][0];
     }
    myNewList.push( tb.interval.list[0] );
    tb.interval.list.shift();
    }
   tb.interval.list = myNewList;
   if ( myMinVal !== 0 ) {
    myDate = new Date();
    tb.interval.ms = myMinVal - myDate.getTime(); 
    }
   else {
    tb.interval.ms = 100;
    }
   while ( tb.interval.addlist.length > 0 ) {
    tb.interval.list.push( tb.timer.addlist.pop() );
    }
   tb.timer.add( 'tb.interval.timeout()', tb.interval.ms);
   } 
  },

 destroy: function( pIdentifier ) {
  var myNewlist = [];
  var i=0;
  for ( i in tb.interval.list ) {
   if ( tb.interval.list[i][2] != pIdentifier ) {
    var myObj = tb.misc.cloneObj( tb.interval.list[i] );
    myNewlist.push( myObj ); 
    }
   }
  tb.interval.list = myNewlist;
  }
  
 };

tb.misc = {
 idCounter:0,
 condition: 'x',
 callback: 'y',
 // public
 
 nop: function() {
  },
 
 wait: function ( pCondition, pCallback, pFrequency ) {
  this.condition = pCondition;
  this.callback = pCallback;
  if ( isNaN( pFrequency ) === true ) {
   pFrequency = 100;
   }
  var myResult = eval( pCondition );
  if ( myResult === false ) {
   var myToFunction = 'tb.misc.wait("'+pCondition+'","'+pCallback+'",'+pFrequency+')';
   tb.timer.add( myToFunction, pFrequency );
   }
  else {
   eval(  pCallback  );
   }
  },

 cloneObj: function( pObj ) {
  var myObj = {};
  for ( var i in pObj ) {
   myObj[i] = pObj[i];
   }
  return myObj;
  },
  
 getid: function() {
  var myDate = new Date();
  this.idCounter = '_'+myDate.getTime()+'_'+Math.random().toString().replace( /\./, '');
  return this.idCounter;
  }
  
 };

tb.cache = {
 list:[], 

 set: function ( pIdentifier, pContent ) {
  var myEntry = [ pIdentifier, pContent ];
  var myIndex = this.findindex( pIdentifier );
  if (  myIndex > -1 )  {
   this.list[myIndex][1] = pContent;
   return;
   }
  this.list.push( myEntry );  
  },

 get: function ( pIdentifier ) {
  var myIndex = this.findindex( pIdentifier );
  if (  myIndex > -1 )  {
   return this.list[myIndex][1];
   } 
  return false;
  },
  
 extract: function ( pIdentifier ) {
  var myIndex = this.findindex( pIdentifier );
  if (  myIndex > -1 )  {
   var myRet = this.list[myIndex][1];
   this.destroy( pIdentifier );
   return myRet;
   } 
  return false;
  },
  
 findindex: function ( pIdentifier ) {
  var i=0;
  for ( i = 0; i < this.list.length; i++ ) {
   if ( this.list[i][0] == pIdentifier )  {
    return i;
    }
   }
  return -1;
  },

 // private
 
 destroy: function ( pIdentifier ) {
  var myNewlist = [];
  var i=0;
  for ( i in this.list ) {
   if ( this.list[i][0] != pIdentifier ) {
    var myObj = tb.misc.cloneObj( this.list[i] );
    myNewlist.push( myObj ); 
    }
   }
  this.list = myNewlist;
  }
    
 };

tb.request = {
 count: 0,
 interval: 50,
 msoft: [ 
  'MSXML2.XMLHTTP.5.0',
  'MSXML2.XMLHTTP.4.0',
  'MSXML2.XMLHTTP.3.0',
  'MSXML2.XMLHTTP',
  'Microsoft.XMLHTTP'
  ],
 
 // public
 
 add: function ( pResponseXmlHandler, pMethod, pUrl, pParms, pIsAsync ) {
  var myIndex = tb.misc.getid();
  var myUid = 'tb'+myIndex;
  var myXmlreq = false;
  var msg = '';
  
  tb.request.inc();

  // proxy disable
  if ( pUrl.indexOf( '/?/' ) > -1 ) { // its a CakePHP service, POST only.
   pMethod = 'POST';
   if ( pParms === null || pParms === '') {
    pParms = 'tbUid='+myUid;          // twobirds specific
    }
   else { // parms given
    pParms = pParms+'&tbUid='+myUid;  // twobirds specific
    }
   }
  else {
   pUrl += ( pUrl.indexOf('?') < 0 ? '?' : '&' ) +'tbUid='+myUid;
   }

  myXmlreq = tb.request.getConnection( myUid );
  if ( myXmlreq ) {
   if ( pMethod == 'GET' && pParms !== null ) {
    pUrl = pUrl + '&' + pParms;
    }
   if ( pMethod == 'POST' ) {
    myXmlreq.connection.open('POST', pUrl, pIsAsync);
    }
   else {
    myXmlreq.connection.open('GET', pUrl, pIsAsync);
    } 
   if ( pIsAsync === true ) {
    tb.request.handlereadystate( myXmlreq, pResponseXmlHandler);
    }
   if ( pMethod == 'POST' ) {
    if ( pParms !== null ) {
     myXmlreq.connection.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
     myXmlreq.connection.send(pParms);
     }
    else {
     myXmlreq.connection.send(null);
     }
    }
   else {
    myXmlreq.connection.send(null);
    }
   if ( pIsAsync === false ) {
    if ( myXmlreq.connection.status >= 200 && myXmlreq.connection.status < 300 ) {
     tb.request.dec();
     pResponseXmlHandler( myXmlreq.connection.responseXML, myXmlreq.connection.responseText);
     }
    else {
     msg=myXmlreq.connection.status+': '+myXmlreq.connection.statusText;
     }
    }
   if ( pMethod == 'POST' ) {
    return myXmlreq;
    }
   else {
    return null;
    }
   }
  else {
   return false;
   }
  },
 
 // private
 
 inc: function () {
  tb.request.count += 1;
  if ( document.getElementById( 'loadingindicator') ) { 
   document.getElementById( 'loadingindicator' ).style.visibility = 'visible';
   }
  },

 dec: function () {
  tb.request.count -= 1;
  if ( tb.request.count < 1) {
   if ( document.getElementById( 'loadingindicator' ) ) {
    document.getElementById( 'loadingindicator' ).style.visibility = 'hidden';
    }
   }
  },
 
 addhandler: function( pIdentifier, pCallback ) {
  tb.cache.set( pIdentifier, pCallback );
  },
  
 getConnection: function ( pIdentifier ) {
  var myObj = {};
  var myHttp;
  try {
   myHttp = new XMLHttpRequest();
   myObj = { connection:myHttp, identifier:pIdentifier };
   }
  catch(e) {
   for(var i=0; i<tb.request.msoft.length; ++i){
    try {
     myHttp = new ActiveXObject( tb.request.msoft[i] );
     myObj = { connection:myHttp, identifier:pIdentifier };
     }
    catch(e){
     }
    }
   }
  finally {
   return myObj;
   }
  },
 
 handlereadystate: function ( pReq, pCallback ) {
  var myConnection = this;
  var myPoll = window.setInterval(
   function(){
    if( pReq.connection.readyState==4 ){
     myConnection.handleTransactionResponse( pReq, pCallback);
     window.clearInterval( myPoll );
     tb.request.dec();
     }
    }
   ,tb.request.interval
   );
  },

 handleTransactionResponse: function( pReq, pCallback ) {
  var httpStatus;
  var responseObject;
  try{
   httpStatus = pReq.connection.status;
   }
  catch(e){
   httpStatus = 13030;
   }
  if( httpStatus >= 200 && httpStatus < 300 ){
   responseObject = tb.request.createResponseObject( pReq, pCallback.argument);
   pCallback.apply(pCallback, [responseObject.responseXml, responseObject.responseText, responseObject]);
   }
  tb.request.release(pReq);
  },

 createResponseObject:function(pObj, pCallbackArg) {
  var myObj = {};
  myObj.tId = pObj.identifier;
  myObj.status = pObj.connection.status;
  myObj.statusText = pObj.connection.statusText;
  myObj.allResponseHeaders = pObj.connection.getAllResponseHeaders();
  myObj.responseText = pObj.connection.responseText;
  myObj.responseXML = pObj.connection.responseXML;
  if(pCallbackArg){
   myObj.argument = pCallbackArg;
   }
  return myObj;
  },

 release: function( pReq ) {
  pReq.connection = null;
  delete pReq.connection;
  pReq = null;
  }  

 };
