/******************************************************************************
 * cshout.js
 * ----------------------------------------------------------------------------
 * DO NOT MODIFY OR REMOVE THIS COPYRIGHT SECTION
 * ----------------------------------------------------------------------------
 * Author       : Tien D. Tran (http://coolersport.info)
 * Copyright    : 2006 (c) Tien D. Tran
 * Application  : CShout
 * Version      : 2.0
 * Date Started : 2005/01/01
 * Last Modified: 2006/09/28 15:02:16
 *
 * This is a shoubox written in php and uses text file as database
 *
 * INSTALLATION:
 *             View installation.html
 * HOW TO USE THE SHOUTBOX:
 *             After installing successfully, click on ? button on the shoutbox
 *
 * Visit http://coolersport.info for any update of this shoutbox
 *
 ******************************************************************************/

function CShout() {
   /********************** CONFIGURATIONS **********************/
   this.url = '/cshout/cshout.php';
   this.inputentry = 'top'; // 'top' or 'bottom'
   this.width = 151;
   this.height = 300;
   this.layout = 0; // 0 or 1
   this.shouterlength = 12;
   this.adminColor = ['#415274', '#AA0000'];
   this.buttonColor = ['#415274', '#808080'];
   /******************* END OF CONFIGURATIONS *******************/

   /********** DO NOT MODIFY THE CODE BELOW THIS LINE ***********/
   /****************** UNLESS YOU UNDERSTAND IT *****************/
   this.httpObj = this.createHttpRequestObject();
   this.cache = new Array();
   this.instance = 0;
   this.isProcessing = false;
   this.page = 1;
   this.pages = 1;
   this.smileys = null;
}

/*
 * Create an instance of XMLHttpRequest object
 */
CShout.prototype.createHttpRequestObject = function() {
   var httpObj;
   try {
      httpObj = new XMLHttpRequest();
   } catch(e) {
      var XmlHttpVersions = new Array('MSXML2.XMLHTTP.6.0','MSXML2.XMLHTTP.5.0','MSXML2.XMLHTTP.4.0','MSXML2.XMLHTTP.3.0','Microsoft.XMLHTTP','MSXML2.XMLHTTP');
      for (var i=0; i<XmlHttpVersions.length && !httpObj; i++) {
         try {
            httpObj = new ActiveXObject(XmlHttpVersions[i]);
         } catch (e) {}
      }
   }
   if (!httpObj)
      alert("Error creating the XMLHttpRequest object. Your browser may not support this application.\nOld version of CShout will be used instead.");
   else
      return httpObj;
}

/*
 * Wrapper to make AJAX requests
 */
CShout.prototype.CDownloadUrl = function() {
   if (!this.httpObj) return;
   if (this.cache.length<4) {
      this.isProcessing = false;
      return;
   } else {
      this.isProcessing = true;
   }
   var method = this.cache.shift();
   var url = this.cache.shift();
   var parameters = this.cache.shift();
   var func = this.cache.shift();
   this.httpObj.onreadystatechange = function() {
      if(cshout.httpObj.readyState == 4){
         if (cshout.httpObj.status == 200) {
            try {
               var contenttype = cshout.httpObj.getResponseHeader('Content-Type');
               if (contenttype.indexOf('xml')>-1) {
                  func(cshout.httpObj.responseXML);
               } else {
                  func(cshout.httpObj.responseText);
               }
            } catch(e) {
               alert('Error retrieving response data: ' + e.message);
            }
         } else {
            func('Error: '+cshout.httpObj.status);
         }
         if (cshout.cache.length<4) {
            cshout.isProcessing = false;
         } else {
            cshout.isProcessing = true;
            setTimeout('cshout.CDownloadUrl()', 100);
         }
      }
   };
   try {
      this.httpObj.open(method, url, true);
      if (parameters!=null) {
         this.httpObj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
         this.httpObj.setRequestHeader("Content-length", parameters.length);
         this.httpObj.setRequestHeader("Connection", "close");
         this.httpObj.send(parameters);
      } else {
         this.httpObj.send(null);
      }
   } catch(e) {
      alert('Error connecting to server: ' + e.message);
   }
}

/*
 * AJAX requests stack
 */
CShout.prototype.load = function(method, url, parameters, func) {
   this.cache.push(method, url, parameters, func);
   if (!this.isProcessing) this.CDownloadUrl();
}

/*
 * Show shoutbox form entry
 */
CShout.prototype.showEntry = function() {
   document.write('<div class="sb_formarea">');
   document.write('<input type="text" id="name" size="16" value="Name" maxlength="64" title="Name" class="sb_inputs" onkeydown="if(event.keyCode==13) document.getElementById(\'shout\').focus();" onfocus="if(this.value==\'Name\') this.value=\'\';" onblur="if(this.value==\'\') this.value=\'Name\';"><br>');
   document.write('<input type="text" id="shout" size="16" value="Message" maxlength="1024" title="Message" class="sb_inputs" onkeydown="if(event.keyCode==13) cshout.shoutIt();" onfocus="if(this.value==\'Message\') this.value=\'\';" onblur="if(this.value==\'\') this.value=\'Message\';"><br>');
   document.write('<input type="button" id="shoutit" title="Send message" value=".: Send :." class="sb_buttons" onclick="cshout.shoutIt();"><input type="button" title="Help" value="?" class="sb_buttons" onclick="cshout.showPanel(\'sb_help\');"><br>');
   document.write('<input type="button" id="sb_show_smileys" title="Show smileys panel" value=":)" class="sb_buttons" onclick="cshout.showPanel(\'sb_smileylist\');">');
   document.write('<input type="button" id="sb_show_search" title="Show search entry" value="S" class="sb_buttons" onclick="cshout.showPanel(\'sb_searchquery\');">');
   document.write('<input type="button" id="sb_show_login" title="Show administration login form" value="@" class="sb_buttons" onclick="cshout.showPanel(\'sb_loginform\');">');
   document.write('<input type="button" id="sb_show_pages" title="Show pages navigation" value="P" class="sb_buttons" onclick="cshout.showPanel(\'sb_pagenav\');">');
   document.write('<input type="button" id="sb_prev_page" title="Previous page" value="&lsaquo;" class="sb_buttons" onclick="cshout.getPageContent(\'prev\');">');
   document.write('<span id="sb_pageno">1</span>');
   document.write('<input type="button" id="sb_next_page" title="Next page" value="&rsaquo;" class="sb_buttons" onclick="cshout.getPageContent(\'next\');">');
   document.write('</div>');

   document.write('<div id="sb_smileylist" class="sb_panel"></div>');
   document.write('<div id="sb_searchquery" class="sb_panel"><input type="text" id="q" name="q" size="16" class="sb_inputs" value="Search for..." maxlength="1024" title="Search for..." class="SB_input" onkeydown="if(event.keyCode==13) cshout.searchIt();" onfocus="if(this.value==\'Search for...\') this.value=\'\';" onblur="if(this.value==\'\') this.value=\'Search for...\';"></div>');

   document.write('<div id="sb_loginform" class="sb_panel">');
   document.write('<input type="text" id="u" name="u" size="3" value="name" title="Username" class="sb_inputs" onfocus="if(this.value==\'name\') this.value=\'\';" onblur="if(this.value==\'\') this.value=\'name\';">');
   document.write('<input type="password" id="p" name="p" size="3" value="pass" title="Password" class="sb_inputs" onfocus="if(this.value==\'pass\') this.value=\'\';" onblur="if(this.value==\'\') this.value=\'pass\';" onkeydown="if(event.keyCode==13) cshout.doLogin();">');
   document.write('<input type="button" id="login" name="login" title="Login" value="OK" class="sb_buttons" onclick="cshout.doLogin();">');
   document.write('<input type="button" id="logout" name="logout" title="Logout" value="Logout" class="sb_buttons" style="display:none" onclick="cshout.doLogout();">');
   document.write('</div>');

   document.write('<div id="sb_pagenav" style="display:none;"></div>');
   document.write('<div id="sb_help" class="sb_panel" style="text-align:left;">');
   document.write('<div id="sb_helpcaption">Make a shout</div>');
   document.write('<div id="sb_helptext">Enter your name in the first text box and your message in the second one then click <b style="white-space:nowrap">.: Send :.</b> button.</div>');
   document.write('<div id="sb_helpcaption">Insert emoticons</div>');
   document.write('<div id="sb_helptext">Place the cursor in the second text box where you want to insert an emoticon then click <b>:)</b> button and click on appropriate icon.</div>');
   document.write('<div id="sb_helpcaption">Search old messages</div>');
   document.write('<div id="sb_helptext">Click <b>S</b> button and enter your search query. You can search by date, time, shouter, message or even ip address.</div>');
   document.write('<div id="sb_helpcaption">Page navigation</div>');
   document.write('<div id="sb_helptext">Use <b>&lsaquo;</b> or <b>&rsaquo;</b> buttons to move to previous or next page respectively. Or click <b>P</b> button to jump to any page.</div>');
   document.write('</div>');
   document.write('<div class="sb_formarea" style="color:transparent;font-size:0pt;clear:both;padding-top:5px;height:3px;overflow:hidden;">CShout</div>');
}

/*
 * Toggle panels
 */
CShout.prototype.showPanel = function(id) {
   if (document.getElementById(id).style.display=='block') {
      document.getElementById(id).style.display = 'none';
   } else{ 
      document.getElementById('sb_smileylist').style.display = 'none';
      document.getElementById('sb_searchquery').style.display = 'none';
      document.getElementById('sb_loginform').style.display = 'none';
      document.getElementById('sb_pagenav').style.display = 'none';
      document.getElementById('sb_help').style.display = 'none';
      document.getElementById(id).style.display = 'block';
   }
}

/*
 * Toggle login form's elements
 */
CShout.prototype.showLogin = function(isLogged) {
   var isIn = 'none', isOut = 'none';
   if (isLogged==1)
      isOut = 'inline';
   else
      isIn = 'inline';
   document.getElementById("u").style.display=isIn;
   document.getElementById("p").style.display=isIn;
   document.getElementById("login").style.display=isIn;
   document.getElementById("logout").style.display=isOut;
}

/*
 * Show the shoutbox on the page
 */
CShout.prototype.show = function() {
   if (this.instance>0) return;
   if (this.httpObj) {
      if (this.layout<0 || this.layout>1) this.layout = 0;
      var cstyle = ['',' style="width:'+(this.width)+'px;height:'+this.height+'px;overflow:auto;overflow-x:hidden;"', ' style="width:'+this.width+'px;overflow:auto;overflow-x:hidden;"'];
      document.write('<div style="width:'+(this.width)+'px;margin:0;padding:0;overflow-x:hidden;">');
      document.write('<div class="sb_shoutbox"'+cstyle[this.layout+1]+'>');
      if (this.inputentry=='top') this.showEntry();
      document.write('<div id="sb_shouts" class="shouts"'+cstyle[this.layout]+'></div>');
      if (this.inputentry=='bottom') this.showEntry();
      document.write('</div>');
      document.write('</div>');
      this.getSmileys();
      this.getPageContent(1);
      this.instance++;
   } else {
      var html = document.getElementById('nojs').innerHTML;
      html = html.replace(/&lt;/g, '<').replace(/&gt;/g, '>');
      document.write(html);
      document.getElementById('nojsmessage').style.display = 'none';
   }
}

/*
 * Update page navigation panel
 */
CShout.prototype.updatePages = function() {
   var str = '';
   for (var i=1; i<this.pages+1; i++) {
      if(i==this.page)
         str += '<span>'+i+'</span> ';
      else
         str += '<a href="" onclick="cshout.getPageContent('+i+');return(false);">'+i+'</a> ';
   }
   document.getElementById('sb_pagenav').innerHTML = str;
}

/*
 * Check for valid number
 */
CShout.prototype.isNumeric = function(val) {
   var numChars = "0123456789";
   var retVal = true;
   if (val == "") {
      return false;
   }
   for (i = 0; i < val.length && retVal == true; i++) {
      if (numChars.indexOf(val.charAt(i)) < 0) {
         retVal = false;
      }
   }
   return retVal;
}

/*
 * Show loading progress
 */
CShout.prototype.showProgress = function(status) {
   var disableit = false;
   if (status) {
      document.getElementById('shoutit').value = status;
      document.getElementById('shoutit').style.color = this.buttonColor[1];
      disableit = true;
   } else {
      document.getElementById('shoutit').value = '.: Send :.';
      document.getElementById('shoutit').style.color = this.buttonColor[0];
   }
   ids = ['shoutit','sb_show_smileys','sb_show_search','sb_show_login','sb_show_pages','sb_prev_page','sb_next_page'];
   for (i=0; i<ids.length; i++) {
      document.getElementById(ids[i]).disabled = disableit;
   }
}

/*
 * Load a page from the server
 */
CShout.prototype.getPageContent = function(p) {
   if (this.isNumeric(p)){
      this.page = p;
   } else if (p=='prev') {
      this.page--;
   } else {
      this.page++;
   }
   if (this.page < 1) {
      this.page = 1;
   } else if (this.page > this.pages) {
      this.page = this.pages;
   }
   this.showProgress('Loading...');
   this.load('get', this.url+'?page='+this.page, null, this.handleContent);
}

/*
 * Process data loaded from the server
 */
CShout.prototype.handleContent = function(xmldoc) {
   try {
      var ferror = xmldoc.documentElement.getElementsByTagName('fe'); // fatal error
      if (ferror.length==0) {
         var error = xmldoc.documentElement.getElementsByTagName('e');
         var shouts = xmldoc.documentElement.getElementsByTagName('s');
         var info = xmldoc.documentElement.getElementsByTagName('info')[0];
         var isadmin = (info.getAttribute('islogged')=='1')?true:false;
         var buttons = '';
         var rowidx = 0;
         var html = '';

         for (i=0; i<error.length; i++) {
            html += '<div id="sb_error">'+error[i].childNodes[0].nodeValue+'</div>';
         }
         document.getElementById('sb_show_login').style.color = cshout.adminColor[parseInt(info.getAttribute('islogged'))];
         cshout.showLogin(parseInt(info.getAttribute('islogged')));
         cshout.pages = parseInt(info.getAttribute('pages'));
         document.getElementById('sb_pageno').innerHTML = cshout.page;
         document.getElementById('shout').value = 'Message';
         for (i=0; i<shouts.length; i++) {
            k = shouts[i].getAttribute('k');
            n = shouts[i].getAttribute('n');
            d = shouts[i].getAttribute('d');
            t = shouts[i].getAttribute('t');
            ip = shouts[i].getAttribute('ip');
            s = shouts[i].childNodes[0].nodeValue;
            if (isadmin) buttons = '<a class="sb_delete" href="" onclick="cshout.deleteIt(\''+k+'\');return(false);" title="Delete this shout">x</a><a class="sb_delete" href="" onclick="cshout.checkIP(\''+ip+'\');return(false);" title="Check ip location">ip</a>';
            if (n.length>cshout.shouterlength)
               html += '<div class="sb_shouter" title="'+n+'">'+buttons+n.substring(0,cshout.shouterlength-3)+'&hellip;</div>';
            else
               html += '<div class="sb_shouter">'+buttons+n+'</div>';
            html += '<div class="sb_row'+rowidx+'" title="'+t+' '+d+' '+ip+'">'+s+'</div>';
            rowidx=(rowidx==0)?1:0;
         }
         document.getElementById('sb_shouts').innerHTML = html;
         cshout.updatePages();
      } else {
         alert(ferror[0].childNodes[0].nodeValue);
      }
      cshout.showProgress();
   } catch(e) {
      alert('Error occurred while processing data.\nError message:\n'+e.message+'\n'+xmldoc);
   }
}

/*
 * Get and print smileys panel
 */
CShout.prototype.getSmileys = function() {
   document.getElementById('sb_smileylist').innerHTML = '<div style="text-align:center;margin-top:10px;">Loading smileys...</div>';
   this.load('get', this.url+'?act=smileys', null, function(xmldoc) {
      try {
         var xmlsmileys = xmldoc.documentElement.getElementsByTagName('sm');
         var html = '';
         cshout.smileys = new Array();
         for (i=0; i<xmlsmileys.length; i++) {
            src = xmlsmileys[i].getAttribute('s');
            text = xmlsmileys[i].getAttribute('t').replace(/\'/,'\\u0027').replace(/\"/,'\\u0022');
            if (src) {
               str = '<div title="'+text+'" class="sb_smiley" style="background-image:url('+src+');" onclick="cshout.addSmiley(\''+text+'\');"></div>';
            } else {
               str = '<span title="'+text+'" onclick="cshout.addSmiley(\''+text+'\');">'+text+'</span> ';
            }
            html += str;
            cshout.smileys.push(new Array(text, str));
         }
         document.getElementById('sb_smileylist').innerHTML = '<div><table align="center" border="0"><tr><td>'+html+'</td></tr></table></div>';
      } catch(e) {
         alert('Error occurred while getting smileys.\nError message:\n'+e.message+'\n'+xmldoc);
      }
   });
}

/*
 * Submit a shout
 */
CShout.prototype.shoutIt = function() {
   cshout.showProgress('Shouting...');
   this.load('get', this.url+'?act=shout&name='+Escape(document.getElementById('name').value)+'&shout='+Escape(document.getElementById('shout').value), null, this.handleContent);
}

/*
 * Perform a search
 */
CShout.prototype.searchIt = function() {
   this.showProgress('Searching...');
   this.load('get', this.url+'?act=search&q='+Escape(document.getElementById('q').value), null, this.handleContent);
}

/*
 * Login procedure
 */
CShout.prototype.doLogin = function() {
   this.showProgress('Logging in...');
   this.load('post', this.url, 'act=login&u='+hex_sha1(document.getElementById('u').value)+'&p='+hex_sha1(document.getElementById('p').value), function(xmldoc) {
      document.getElementById('p').value = 'pass';
      var ferror = xmldoc.documentElement.getElementsByTagName('fe'); // fatal error
      if (ferror.length>0) {
         if (ferror[0].childNodes[0].nodeValue=='ok') {
            cshout.getPageContent(cshout.page);
            document.getElementById('sb_show_login').style.color = cshout.adminColor[0];
            cshout.showPanel('sb_loginform');
         } else {
            alert(ferror[0].childNodes[0].nodeValue);
         }
      } else {
         alert('Unexpected error.');
      }
      cshout.showProgress();
   });
}

/*
 * Logout procedure
 */
CShout.prototype.doLogout = function() {
   this.showProgress('Logging out...');
   this.load('post', this.url, 'act=logout', function(xmldoc) {
      var ferror = xmldoc.documentElement.getElementsByTagName('fe'); // fatal error
      if (ferror.length>0) {
         if (ferror[0].childNodes[0].nodeValue=='ok') {
            cshout.getPageContent(cshout.page);
            document.getElementById('sb_show_login').style.color = cshout.adminColor[1];
            cshout.showPanel('sb_loginform');
         } else {
            alert(ferror[0].childNodes[0].nodeValue);
         }
      } else {
         alert('Unexpected error.');
      }
      cshout.showProgress();
   });
}

/*
 * Delete a shout
 */
CShout.prototype.deleteIt = function(k) {
   this.showProgress('Deleting...');
   this.load('get', this.url+'?act=del&k='+k, null, function(data) {
      cshout.getPageContent(cshout.page);
      cshout.showProgress();
   });
}

/*
 * Check location of an ip address
 */
CShout.prototype.checkIP = function(ip) {
   window.open('http://www.geobytes.com/IpLocator.htm?GetLocation&ipaddress='+ip);
}

/*
 * Add a smiley into current message
 */
CShout.prototype.addSmiley = function(s) {
   if (document.getElementById('shout').value=='Message')
      document.getElementById('shout').value = s;
   else
      document.getElementById('shout').value += s;
}

/*
 * Escape a string before submitting
 */
function Escape(s) {
   return escape(s).replace(/\+/,'%2B');
}

/*
 * Singleton instance
 */
cshout = new CShout();
