<!--
/* ******************************************* *
 * twobirds AJAX lib 
 * V 1.0.0 
 * Author: 2002- Frank Th�rigen / phpbuero.de
 * ******************************************* */

/* obsolete for now maybe we need it later on....
var utf8 = { //new oject
 encode: function(rohtext) {
             // dient der Normalisierung des Zeilenumbruchs
             rohtext = rohtext.replace(/\r\n/g,"\n");
             var utftext = "";
             for(var n=0; n<rohtext.length; n++)
                 {
                 // ermitteln des Unicodes des  aktuellen Zeichens
                 var c=rohtext.charCodeAt(n);
                 // alle Zeichen von 0-127 => 1byte
                 if (c<128)
                     utftext += String.fromCharCode(c);
                 // alle Zeichen von 127 bis 2047 => 2byte
                 else if((c>127) && (c<2048)) {
                     utftext += String.fromCharCode((c>>6)|192);
                     utftext += String.fromCharCode((c&63)|128);}
                 // alle Zeichen von 2048 bis 66536 => 3byte
                 else {
                     utftext += String.fromCharCode((c>>12)|224);
                     utftext += String.fromCharCode(((c>>6)&63)|128);
                     utftext += String.fromCharCode((c&63)|128);}
                 }
             return utftext;
         },
         
  decode: function(utftext) {
             var plaintext = ""; var i=0; var c=c1=c2=0;
             // while-Schleife, weil einige Zeichen uebersprungen werden
             while(i<utftext.length)
                 {
                 c = utftext.charCodeAt(i);
                 if (c<128) {
                     plaintext += String.fromCharCode(c);
                     i++;}
                 else if((c>191) && (c<224)) {
                     c2 = utftext.charCodeAt(i+1);
                     plaintext += String.fromCharCode(((c&31)<<6) | (c2&63));
                     i+=2;}
                 else {
                     c2 = utftext.charCodeAt(i+1); c3 = utftext.charCodeAt(i+2);
                     plaintext += String.fromCharCode(((c&15)<<12) | ((c2&63)<<6) | (c3&63));
                     i+=3;}
                 }
             return plaintext;
         }
 }
*/
 
var tbTimer = {
 list: [],
 ms: 50,
 
 timeout: function() {
  if ( tbTimer.list.length < 1 ) {
   var myDiv = document.getElementById('bottomcentercontainer');
   if ( myDiv && myDiv.innerHTML != '' ) {
    myDiv.innerHTML = '';
    }
   window.setTimeout( 'tbTimer.timeout()', tbTimer.ms);
   return;
   }
  else {
   var myNewList = [];
   var myDiv = document.getElementById('bottomcentercontainer');
   if ( myDiv && tbTimer.list.length > 0 ) {
    var myString =  tbTimer.list.length + ': ' + tbTimer.list[0][0] + ', ' +  tbTimer.list[0][1];
    myDiv.innerHTML = myString;
    }
   while ( tbTimer.list.length > 0 ) {
    var myDate = new Date();
    var myTime = myDate.getTime();
    if ( tbTimer.list[0][0] <= myTime ) { // do it now
     var myEval = tbTimer.list[0][1];
     tbTimer.list.shift();
     eval( myEval );
     }
    else { // not yet...
     myNewList.push( tbTimer.list[0] );
     tbTimer.list.shift();
     }
    }
   tbTimer.list = myNewList;
   window.setTimeout( 'tbTimer.timeout()', tbTimer.ms);
   } 
  },

 add: function( pCallback, pTimeMs ) {
  var myDate = new Date();
  var myTime = myDate.getTime() + pTimeMs; // current + offset
  var myArray = [ myTime, pCallback ];
  tbTimer.list.push( myArray );
  //alert( myTime + ': ' + pCallback );
  }
  
 }
window.setTimeout( 'tbTimer.timeout()', 0);


var tbMisc = {
 idCounter:0, // unique counter

 nop: function() {
  },
 
 wait: function ( pCondition, pCallback, pFrequency ) {
  if ( isNaN( pFrequency ) == true ) {
   pFrequency = 100;
   }
  myResult = eval( pCondition );
  if ( myResult == false ) {
   myToFunction = 'tbMisc.wait("'+pCondition+'","'+pCallback+'",'+pFrequency+')';
   tbTimer.add( myToFunction, pFrequency );
   }
  else { // pCondition = true
   eval( pCallback ); // do it now
   }
  },

 getid: function() {
  var myDate = new Date();
  tbMisc.idCounter = myDate.getTime();
  return tbMisc.idCounter;
  }
  
 }

var tbRequest = { // new object
 add: function ( pResponseXmlHandler, pMethod, pUrl, pParms, pIsAsync ) {
  var myParms = '';
  var myIndex = tbMisc.getid();
  var myDate = new Date();
  var myTime = myDate.getTime();
  var myUid = 'tb'+myTime+'_'+myIndex;
  var myXmlreq = false;
  var msg = '';
  
  // proxy disable
  /* 
  Hint: CakePHP does only work with POST params 
  */
  if ( pUrl.indexOf( '/?/' ) > -1 ) { // its a CakePHP service, POST only.
   pMethod = 'POST';
   if ( pParms == null || pParms == '') {
    myParms = 'tbUid='+myUid;          // twobirds specific
    }
   else { // parms given
    myParms = pParms+'&tbUid='+myUid;  // twobirds specific
    }
   tbDebug.add ( '<p><font style="font-weight:bold">CakePHP:</font> '+pUrl+'&nbsp;&nbsp;&nbsp;&nbsp;'+pMethod+': '+myParms+'</p>' );
   //pUrl += '/'+myUid;                 // cake specific
   }
  else { // its a twoBirds service
   if ( pParms == null || pParms == '') {
    myParms = 'tbUid='+myUid;          // twobirds specific
    }
   else { // parms given
    myParms = pParms+'&tbUid='+myUid;  // twobirds specific
    }
   }
  pParms = myParms;
   
  // make request
  if (window.XMLHttpRequest) {
   myXmlreq = new XMLHttpRequest();
   }
  else if (window.ActiveXObject) {
   try { myXmlreq = new ActiveXObject("Msxml2.XMLHTTP"); }
   catch (e1) { 
    try { myXmlreq = new ActiveXObject("Microsoft.XMLHTTP"); }
    catch (e2) {}
    }
   }
  // process request
  if ( myXmlreq ) {
   myXmlreq.onreadystatechange=tbRequest.handler(myXmlreq, pResponseXmlHandler, myIndex);
   if ( pMethod == 'POST' ) {
    myXmlreq.open('POST', pUrl, pIsAsync);
    }
   else {
    if ( pParms != null ) {
     pUrl = pUrl + '?' + pParms;
     }
    myXmlreq.open('GET', pUrl, pIsAsync);
    } 
   if ( pMethod == 'POST' ) {
    if (pParms) {
     myXmlreq.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
     myXmlreq.send(pParms);
     }
    else {
     myXmlreq.send(null);
     }
    }
   else {
    myXmlreq.send(null);
    }
   if ( pIsAsync == false ) { // not asynchronous --> handle response directly !!!
    if ( myXmlreq.status == 200 ) {
     pResponseXmlHandler( myXmlreq.responseXML, myXmlreq.responseText);
     }
    else {
     msg=myXmlreq.status+': '+myXmlreq.statusText;
     }
    }      
   if ( pMethod == 'POST' ) {
    return myXmlreq; // async req ptr
    }
   else {
    return null; // no req ptr avail
    }
   }
  else {
   return false;
   }
  },

 handler: function (pReq, pResponseXmlHandler, pIndex) {
  return function () {
   var msg='';
   if (pReq.readyState == 4) {
    try {
     if (pReq.status == 200) {
      if (pReq.responseXML) {
       pResponseXmlHandler( pReq.responseXML, pReq.responseText);
       }
      else if (pReq.responseText) {
       pResponseXmlHandler( null, pReq.responseText);
       }
      }
     } 
    catch (e) {}
    }
   }  
  }
 }

tbLoader = {
 path:'service/', // start path
 
 js_loadlist:'', // contains identifiers of JS files currently being loaded
 js_list:'',  // contains identifiers of JS files already loaded or loading

 tpl_loadlist:'', // dito for TEMPLATES
 tpl_list:'', 
 tpl_templates:'',
 
 ele_loadlist:'', // dito for ELEMENTS
 ele_list:'',
 
 loading: function ( pType, pIdentifier, pState) {
  switch ( pType ) {
   case 'js': var teststring = tbLoader.js_loadlist; break;
   case 'tpl': var teststring = tbLoader.tpl_loadlist; break;
   case 'ele': var teststring = tbLoader.ele_loadlist; break;
   }
 
  if (pState == null ) {
   if ( teststring.indexOf(pIdentifier) > -1 ) {
    return true; // this file currently being loaded
    }
   else {
    return false;  // this file currently NOT being loaded
    }
   }
  else if (pState == false) { // remove identifier from string
   var myReg=new RegExp(pIdentifier);
   teststring=teststring.replace(myReg, '');
   }
  else { // pState=true: add identifier to string
   teststring += pIdentifier;
   }

  switch ( pType ) {
   case 'js': tbLoader.js_loadlist = teststring; break;
   case 'tpl': tbLoader.tpl_loadlist = teststring; break;
   case 'ele': tbLoader.ele_loadlist = teststring; break;
   }
 
  },
 
 jsload: function( pModule, pElement) {
  if (tbDebug.debugLevel > 1 ) tbDebug.add("<p>Element <font color='red'><b>loading: </b></font>" + pModule + '.' + pElement + "</p>");
  var myUrl = tbLoader.path + 'service.php?url=twobirds/modules/' + pModule + '/js/' + pElement + '.js';
  var script = document.createElement('script');
  script.setAttribute('src', myUrl); //URL zuweisen
  script.setAttribute('type','text/javascript');
  document.getElementsByTagName('head')[0].appendChild(script); // add JS file
  },
 
 cssload: function( pModule, pElement) {
  var myUrl = tbLoader.path + 'service.php';
  var myParms = 'url=twobirds/modules/twobirds/isFile(f).php&f=twobirds/modules/' + pModule + '/css/' + pElement + '.css';
   tbRequest.add(tbLoader.cssload_callback, 'GET', myUrl, myParms, true);
  },

 cssload_callback: function( pXml, pText) {
  if ( pText != 'false' ) { // there is a css file
   var link = document.createElement('link');
   link.setAttribute('rel','STYLESHEET');
   link.setAttribute('type','text/css');
   link.setAttribute('href', pText); //URL zuweisen
   document.getElementsByTagName('head')[0].appendChild(link); // add CSS file
   }
  },

 tplload: function( pModule, pElement) {
  var myIdentifier = pModule + '.' + pElement + ';';
    
  if ( this.tpl_list.indexOf( myIdentifier ) > -1 ) { // already loaded or loading
   return;
   }
  else { // load tpl
   if ( this.loading('tpl', myIdentifier ) == false ) {
    if (tbDebug.debugLevel > 1 ) tbDebug.add("<p><font color='darkgreen'>Template</font> <font color='red'><b>loading: </b></font>" + pModule + '.' + pElement + "</p>");
    this.tpl_list += myIdentifier;
    this.loading( 'tpl', myIdentifier, true );
    var myUrl = tbLoader.path + 'service.php';
    var myParms = 'url=twobirds/modules/' + pModule + '/tpl/' + pElement;
    tbRequest.add( tbLoader.tplload_callback, 'GET', myUrl, myParms, true );
    }
   }
  },
  
 tplload_callback: function ( pXml, pText) {
  var myIdentifierStart = pText.indexOf('<!--')+4;
  var myIdentifierEnd = pText.indexOf('-->');
  var myIdentifier = pText.slice(myIdentifierStart,myIdentifierEnd);
  var myData = new Array ( pXml, pText.slice( pText.indexOf('>')+1 ) ); // cut out identifier
  var myEntry = new Array ( myIdentifier, myData );
  tbLoader.tpl_templates.push(myEntry);
  if (tbDebug.debugLevel > 1 ) tbDebug.add("<p><font color='darkgreen'>Template</font> <font color='red'><b>loaded (CB): </b></font>" + myIdentifier + "</p>");
  tbLoader.loading('tpl', myIdentifier, false);
  },

 tplget: function( pModule, pElement) {
  var myIdentifier = pModule + '.' + pElement + '.html.tpl;'; 
  for ( i = 0; i < tbLoader.tpl_templates.length; i++ ) {
   if ( tbLoader.tpl_templates[i][0] == myIdentifier )  {
    return tbLoader.tpl_templates[i][1][1];
    }
   }
  return false;
  },
  
 eleload: function ( pModule, pElement) {
  var myIdentifier = pModule + '.' + pElement + ';';
  if ( this.ele_list.indexOf( myIdentifier ) > -1 ) { // already loaded or loading
   return;
   }
  else { // load files
   if ( this.loading('ele', myIdentifier ) == false ) { // not already loading.
    this.ele_list += myIdentifier;
    this.loading( 'ele', myIdentifier, true ); 
    this.jsload( pModule, pElement);
    this.cssload( pModule, pElement);
    } 
   }
  }

 }
tbLoader.tpl_templates=new Array();

var tbContainer = { // new object
  
 creatediv: function ( pDivId, pId ) { // insert a new div
  var myParentDiv = document.getElementById( pDivId );
  if ( myParentDiv ) {
   var myDiv = document.createElement('div');
   myDiv.id = pId;
   myDiv.display='inline';
   if ( myParentDiv.hasChildNodes() == false ) {
    myParentDiv.appendChild(myDiv);
    }
   else {
    var myBeforeDiv = myParentDiv.firstChild;
    myParentDiv.insertBefore( myDiv, myBeforeDiv );
    }
   return document.getElementById( pId );
   }
  tbError.add( 'tbContainer.creatediv(): pDivId not found!' , '', pDivId);
  return false;
  },
  
 addfirst: function ( pDivId, pHtml ) { // insert a new firstchilds html code
  var myDiv = document.getElementById( pDivId );
  if ( myDiv ) {
   var myId = 'div'+tbMisc.getid();
   var myDiv = tbContainer.creatediv ( pDivId, myId );
   myDiv.innerHTML = pHtml;
   return myId;
   }
  tbError.add( 'tbContainer.addfirst(): pDivId not found!' , '', pDivId);
  return false;
  },
  
 addlast: function ( pDivId, pHtml ) { // insert a new lastchilds html code
  var myDiv = document.getElementById( pDivId );
  if ( myDiv ) {
   var myId = tbContainer.addfirst( pDivId, pHtml );
   tbContainer.movelast(myDiv);
   return myId;
   }
  tbError.add( 'tbContainer.addlast(): pDivId not found!' , '', pDivId);
  return false;
  },
  
 replace: function ( pDivId, pHtml ) { // replace div content
  var myDiv = document.getElementById( pDivId );
  if ( myDiv ) {
   document.getElementById( pDivId ).innerHTML = pHtml;
   return true;
   }
  tbError.add( 'tbContainer.replace(): pDivId not found!' , '', pDivId);
  return false;
  },
  
 remove: function ( pDivId ) {  // remove container inner div
  var myDiv = document.getElementById( pDivId );
  if ( myDiv ) {
   var myIC = document.getElementById(pDivId).parentNode;
   myIC.removeChild( myDiv );
   return true;
   }
  tbError.add( 'tbContainer.remove(): pDivId not found!' , '', pDivId);
  return false;
  },
  
 movefirst: function ( pDivId ) { // move container innerdiv to first place
  while ( tbContainer.moveup( pDivId ) == true ) {
   }
  },
  
 movelast: function ( pDivId ) { // move container innerdiv to last place
  while ( tbContainer.movedown( pDivId ) == true ) {
   }
  },
  
 moveup: function ( pDivId ) { // move container innerdiv up one place
  var myDiv1 = document.getElementById( pDivId );
  var myDiv2 = myDiv1.previousSibling;
  if ( typeof myDiv1 != 'undefined' ) {
   if ( myDiv2 ) {
    tbContainer.swapnode( myDiv1, myDiv2 );
    return true;
    }
   }
  return false;
  },
  
 movedown: function ( pDivId ) { // move container innerdiv down one place
  var myDiv1 = document.getElementById( pDivId );
  var myDiv2 = myDiv1.nextSibling;
  if ( myDiv1 ) {
   if ( myDiv2 ) {
    tbContainer.swapnode( myDiv1, myDiv2 );
    return true;
    }
   }
  return false;
  },
 
 swapnode: function (p1, p2) {  
  if (p1 != p2) {
   var pc1 = p1.cloneNode(true);
   var pc2 = p2.cloneNode(true);
   p2.parentNode.replaceChild(pc1,p2);
   p1.parentNode.replaceChild(pc2,p1);
   } 
  }
  
 }

var tbElement = {
 list: '',
  
 load: function ( pModule, pElement ) { // preloader, handy for optimization, loads JS and CSS
  tbLoader.eleload( pModule, pElement );
  },
  
 show: function ( pDivId, pModule, pElement, pParms, pFrequency ) { // loads JS and (CSS if exists) + displays element in div(id)
  if ( tbDebug.debugLevel > 1 ) tbDebug.add("<p>Element <font color='blue'><b>instance: </b></font>" + pModule + '.' + pElement + " in " + pDivId + "</p>");
  tbLoader.eleload( pModule, pElement );
  var myIdentifier = pModule + '.' + pElement + ';';
  var myCondition = 'tbLoader.loading(\'ele\', \''+myIdentifier+'\', null ) == false';
  var myCallback = 'if (typeof '+pElement+'.init == \'function\') '+pElement + '.init(\'' + pDivId + '\')';
  var myFrequency = typeof pFrequency != 'number' ? pFrequency : 100 ; // 100ms is default
  tbMisc.wait(myCondition, myCallback, myFrequency);
  },

 templatewait: function ( pCallback, pModule, pElement, pParms, pFrequency ) { // waits for template tb loaded, then calls callback func
  var myIdentifier = pModule + '.' + pElement + '.html.tpl;';
  var myCondition = 'tbLoader.loading(\'tpl\', \''+myIdentifier+'\', null ) == false';
  var myFrequency = typeof pFrequency != 'number' ? pFrequency : 100 ; // 100ms is default
  tbLoader.tplload( pModule, pElement+'.html.tpl');
  if ( tbLoader.loading('tpl', myIdentifier ) == true ) {
   // prepare (wait for template)
   var myCondition = 'tbLoader.loading(\'tpl\', \'' + myIdentifier + '\' ) == false';
   var myFrequency = 20; // 100ms is default
   tbMisc.wait( myCondition, pCallback, myFrequency);
   }
  else {
   eval(pCallback);
   }
  }
 }
tbElement.list = new Array();
 
var tbBody = { // new object
 show: function() {
  tbElement.show('tb_body', 'index', 'index_body', null, 20); // will be first and only one loading at that time - 
                                                              // hence the small frequency (ms waiting for) value
  }
 }
 
var tbCache = { // new object
 // Caching disabled for MSIE (tbd)
 list:'', 


 add: function ( pModule, pFile, pXml, pText ) {

  var myS = /Microsoft/;
  if ( navigator.appName.indexOf(myS) != -1 ) return;
  /* *** */
  },

 get: function ( pModule, pFile ) {

  var myS = /Microsoft/;
  if ( navigator.appName.indexOf(myS) != -1 ) return false;
  /* *** */  
  return false;
  }
 }
tbCache.list=new Array();

 
/* 
 Debugging
 */
var tbDebug = { // new object
 debugLevel:0, // bool show debug messages
 isDebug:false, 
 debugMsgs:'', // debug message string (while debug div not present)
 divId:'debug', // id of div that will display the messages
 
 setDebug: function( pDebug ) { // toggles debug on/off
  if (pDebug > 0) {
   tbDebug.isDebug=true;
   tbDebug.showMsgs( true );
   window.onerror = tbError.add;
   }
  else {
   document.getElementById(this.divId).innerHTML = '<p color="darkblue"><b><u><i>Debug Output:</i></u></b></p>'; // clear dbg string
   tbDebug.showMsgs( false );
   tbDebug.isDebug=false;
   window.onerror = null;
   }
  },

 add: function ( pMsg ) { // add a new debug message
  if ( tbDebug.isDebug ) {
   tbDebug.debugMsgs += pMsg;
   try {
    document.getElementById('debug').innerHTML += tbDebug.debugMsgs;
    document.getElementById('debug').parentNode.scrollTop = document.getElementById('debug').parentNode.scrollHeight;
    tbDebug.debugMsgs = '';
    }
   catch (e) {
    }
   }
  },

 show: function () {
  if ( tbDebug.debugLevel == 0 ) {
   tbDebug.debugLevel=1;
   tbDebug.isDebug = true;
   return;
   }
  if ( typeof document.getElementById( tbDebug.divId ) != 'undefined' ) { 
   if ( document.getElementById(tbDebug.divId).style.display == 'none' ) {
    document.getElementById('innercontentcontainer').style.display = 'none';
    document.getElementById(tbDebug.divId).style.display = '';
    }
   else {
    document.getElementById('innercontentcontainer').style.display = '';
    document.getElementById(tbDebug.divId).style.display = 'none';
    tbDebug.debugLevel = 0;
    tbDebug.isDebug = false;
    try {
     document.getElementById(tbDebug.divId).innerHTML = '<p color="darkblue"><b><u><i>Debug Output:</i></u></b></p>';
     }
    catch (e) {}
    } 
   }
  }
 }

/* 
 Error handling
 */
var tbError = {
 add: function (pMsg, pFile, pLine) {
  var myDebugHtml  = "<p><font color='red'><b>Error: </b></font>" + pMsg + "<br /><b>File: </b>" + pFile + "<br /><b>Line: </b>" + pLine;
  var myDebugMsg  = "Error: " + pMsg + "\nFile: " + pFile + "\nLine" + pLine;
  tbDebug.show( true );
  tbDebug.add( myDebugHtml );
  alert(myDebugMsg);
  return true;
  }
 }
window.onerror=tbError.add;

-->
