/* 
 * httpops.js -- JavaScript module of dictionary search for interaction with server side.
 * Author: Muhammad Abdulla. 
 * Copyleft 2005-2008.
 */

var userid ;  
var count = 0 ;

MaxCount = 11; // maximum number of phrases to be kept for recent search history
StatInterval = 10000; // dictionary statistics polling interval in milliseconds
rarray = new Array();

var qryreq ; // HTTPXML object for query requests
var nbrreq ; // HTTPXML object for neihgbor requests
var statreq ; // HTTPXML object for statistics 

var cur_phrase = "";
var cur_dtype  = "";
var cur_highlight  = "";

var chinpart = "";
var pinpart = "";

var ds_total; // copy of total number of queries to do local updates

function new_req ( )
{
   var newreq ;

   try {
      if (window.XMLHttpRequest) {
         newreq = new XMLHttpRequest();
      // branch for IE/Windows ActiveX version
      } else if (window.ActiveXObject) {
         newreq = new ActiveXObject("Microsoft.XMLHTTP");
      }
   } catch (e) {
      // do nothing here
   }

   return newreq ;
}

function getHint ( phrase )
{
   var hasSpace, hasTone;
   var i, code, ch, str;

   if ( phrase == "" ) {
      return "none";
   }

   // test for Arabic Presentation Forms (A, B) letters
   for ( i = 0; i < phrase.length; i++ ) {
      code = phrase.charCodeAt(i);

      if ( (0xFB50 <= code && code <= 0xFDFF) || (0xFE70 <= code && code <= 0xFEFF) ) {
         return "uypf";
      }
   }

   if ( isValidCn(phrase) ) {
      return "chin";
   }
   
   var inchin = false;
   var inpin  = false;
   var sidx; // switch index

   // look for phrase that start with chinese characters following by pinyin: (in c*p* pattern)
   for ( i = 0; i < phrase.length; i++ ) {
      code = phrase.charCodeAt(i);
      ch = phrase.charAt(i);
      str = String.fromCharCode(code);

      if ( inchin == false ) {
         if ( isValidCn(str) ) { // start with Chinese characters
            inchin = true;
         } else { // does not start with Chinese characters, no need to continue
            break;
         }
      } else {
         if ( inpin == false ) {
            if ( isValidCn(str) ) {
               continue;
            } else if ( isValidPinyin(str) ) { // switching to pinyin
               inpin = true;
               sidx = i;
            } else {
               break;
            }
         } else { // inpin == true
            if ( isValidPinyin(str) ) {
               continue;
            } else {
               inpin = false;
               break;
            }
         }
      }
   }

   //will only be true if phrase follows c*p* pattern (c: chinese char, p: pinyin)
   if ( inchin && inpin ) { 
      chinpart = phrase.substr(0, sidx);
      pinpart = phrase.substring(sidx);
      return "chinpin";
   }

   for ( i = 0; i < phrase.length; i++ ) {
      code = phrase.charCodeAt(i);
      ch = phrase.charAt(i);

      if ( ch == ' ' ) {
         hasSpace = true;
      } else if ( ch == 'ā' || ch == 'á' || ch == 'ǎ' || ch == 'à' || 
                  ch == 'ē' || ch == 'é' || ch == 'ě' || ch == 'è' || 
                  ch == 'ī' || ch == 'í' || ch == 'ǐ' || ch == 'ì' || 
                  ch == 'ō' || ch == 'ó' || ch == 'ǒ' || ch == 'ò' || 
                  ch == 'ū' || ch == 'ú' || ch == 'ǔ' || ch == 'ù' || 
                  ch == 'ǖ' || ch == 'ǘ' || ch == 'ǚ' || ch == 'ǜ' ) { // looks like it has tones
         hasTone = true;
      } 
   }

   if ( hasSpace && hasTone ) {
      return "pin";  // regular pinyin with tones and space
   } else if ( hasSpace ) {
      return "ntn";  // pinyin with tones, but no space
   } else if ( hasTone ) {
      return "nsp";  // pinyin without tone, but with space
   } else {
      return "ntnnsp";  // pinyin with no tone and space
   } 
}

function trim(str)
{
   return str.replace(/^\s*|\s*$/g,"");
}

/********************* Query Phrase **********************/

function do_query(orig_phrase, dt, highlight, single_search) {
   var phrase = trim(orig_phrase);

   var hint    = "";  // give hints to server program regarding the query
   var sentform = "";  // form of the entry search, like "exact", "ends with", etc. 

   qryreq = new_req() ;

   var derr = document.getElementById ( "err" ) ;
   var url  = "/cgi/mdict" ;

   if ( dt ) {
      /* if dt is given, this usually means do_query click on a link,
      * so we have to scroll to top first, and scroll down lest the definition
      * is invisible if the clicked link is far down in the page.
      */
      var tf = document.getElementById ( "phrase" ) ; 
      selectDictype(dt)
      tf.value = phrase;
      derr.style.display = "none" ;
      var curDictype = dt; 
   } else {
      var curDictype = document.getElementById('dictype').value ;
   }

   if ( highlight ) {
      cur_highlight = highlight;
   } else {
      cur_highlight = "";
   }

   // record current values for later use
   cur_phrase = phrase;
   cur_dtype  = curDictype;


   if ( curDictype == 'cn_cn' || curDictype == 'cn_ug' ) {
      phrase = phrase.toLowerCase();
      hint = getHint(phrase);

      // due to different forms of putting space within pinyin, we
      // just remove space within and search for the merged
      if ( hint == "pin" ) {
         phrase = phrase.replace(/\s*/g, '');
         hint = "nsp";
      } else if ( hint == "ntn" ) {
         phrase = phrase.replace(/\s*/g, '');
         hint = "ntnnsp";
      } else if ( hint == "chinpin" ) {
         pinpart = pinpart.replace(/\s*/g, '');
      }
   }

   if ( curDictype == 'ug_ug' || curDictype == 'ug_en' || curDictype == 'ug_cn' ) {
      hint = getHint(phrase); // check for Presentation Form letters (extended region)
      sdef_name = 'uy_sdef';
      sdeform_name = 'sdeform';
   } else if ( curDictype == 'en_en' || curDictype == 'en_ug' || curDictype == 'en_cn' ) {
      sdef_name = 'en_sdef';
      sdeform_name = 'en_sdeform';
   } else if ( curDictype == 'cn_cn' || curDictype == 'cn_ug' || curDictype == 'cn_en' ) {
      sdef_name = 'cn_sdef';
      sdeform_name = 'cn_sdeform';
   }

   var sd = document.getElementById(sdef_name);
   var wd = document.getElementsByName(sdeform_name);
   if ( sd && sd.checked ) {
      hint = "sdef";
      if ( wd ) {
         if ( (wd[0].value == 'whole' && wd[0].checked == true) ||
              (wd[1].value == 'whole' && wd[1].checked == true) ) {
             hint = "wdef";
         }
      }
   }

   if ( single_search ) {
      sentform = "exact";
   } else {
      var sform_name;
      var sdef_name;
      var sdeform_name;

      if ( curDictype == 'ug_ug' || curDictype == 'ug_en' || curDictype == 'ug_cn' ) {
         sform_name = 'sentform';
      } else if ( curDictype == 'en_en' || curDictype == 'en_ug' || curDictype == 'en_cn' ) {
         sform_name = 'en_sentform';
      } else if ( curDictype == 'cn_cn' || curDictype == 'cn_ug' || curDictype == 'cn_en' ) {
         sform_name = 'cn_sentform';
      }

      var ed = document.getElementsByName(sform_name);
      if ( ed ) {
         for ( i = 0; i < ed.length; i++ ) {
            if ( ed[i].checked == true ) {
               sentform = ed[i].value;
            }
         }
      }
   }

   // general form of POST data: req.send('var1=data1&var2=data2');
   data = "phrase=" + encodeURIComponent(phrase) + "&tok=" + gt(phrase) + "&dictype=" + curDictype + "&sentform=" + sentform ;
   if ( hint != "" ) {
      data = data + "&hint=" + hint;
      if ( hint == "chinpin" ) {
         data = data + "&chinpart=" + chinpart + "&pinpart=" + pinpart;
      }
   }

   if ( phrase == "" ) { // don't check blank phrases
      derr.innerHTML = "ﺉﻯﺯﺩەﻱﺩﻰﻏﺎﻧ ﺱۆﺰﻧﻯ ﻙﻯﺭگۈﺯۈڭ."; 
      derr.style.display = "block" ;
      return ; 
   }

   // Execute the request
   try {
      if (qryreq) {
         qryreq.onreadystatechange = checkQuery ;

         qryreq.open( 'POST', url, true );
         qryreq.setRequestHeader('REFERER', location.href);
         qryreq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
         qryreq.send( data );

         var t = document.getElementById('divstat_total');
         if ( t ) {
           ds_total++;
           t.innerHTML = "" + num_fmt(ds_total);
         }
      }
   } catch (e) {
      // do nothing
   }

   updateRecentSearches ( phrase, curDictype )
   return false ;
}

function checkQuery() {
   var dw     = document.getElementById ( "divwait" ) ;
   var ddef   = document.getElementById ( "divdef" ) ;

   switch (qryreq.readyState) {
      case 1:
         dw.style.visibility = 'visible' ;
         break ;
      case 2:
         break;
      case 3:
         break;
      case 4:
         dw.style.visibility = 'hidden' ;
         if (qryreq.status == 200) {
            var rtext = qryreq.responseText 
            var ch = rtext.charAt(0);
            if ( ch == ' ' ) { // a space means phrase was found
               getNeighbours(); // show neighboring words
            }
            if ( cur_highlight != "" ) {
               var idx = rtext.indexOf('<!-- -->');
               var rtext2 = "";
               if ( idx > -1 ) {
                  rtext2 = rtext.substr(idx);
                  rtext  = rtext.substr(0, idx);
               }
               var bspan = '<span style="color: red">';
               var espan = '</span>';
               var regex = new RegExp(cur_highlight, "g"); 
               rtext = rtext.replace(regex, bspan + cur_highlight + espan );
               rtext = rtext + rtext2;
            }
            ddef.innerHTML = rtext ;
            ddef.style.display = "block" ;
         } else {
            // don't scare the user
         }
         break;
   }    
}

function getNeighbours()
{
   var hint    = "";  // give hints to server program regarding the query
   var url  = "/cgi/mdict" ;

   if ( cur_dtype != 'ug_ug' ) {
      return;
   }

   var p = cur_phrase;

   var d = document.getElementById('nwords');

   if ( !d ) {
      return;
   }

   d.style.display = 'block';

   nbrreq = new_req() ;

   hint = getHint(p);
   // general form of POST data: req.send('var1=data1&var2=data2');
   data = "phrase=" + encodeURIComponent(p) + "&tok=" + gt(p) + "&dictype=" + "uul" ;
   if ( hint == "uypf" ) {
      data = data + "&hint=" + hint;
   }

   // Execute the request
   try {
      if (nbrreq) {
         nbrreq.onreadystatechange = checkNeighbor ;

         nbrreq.open( 'POST', url, true );
         nbrreq.setRequestHeader('REFERER', location.href);
         nbrreq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
         nbrreq.send( data );
      }
   } catch (e) {
      // do nothing
   }
}

function checkNeighbor() {
   switch (nbrreq.readyState) {
      case 1:
         break ;
      case 2:
         break;
      case 3:
         break;
      case 4:
         if (nbrreq.status == 200) {
            var rtext = nbrreq.responseText 
            populateNeighbors(rtext);
         } else {
            // don't scare the user
         }
         break;
   }    
}

var has_prev = true;
var has_next = true;
var prev_list;
var next_list;
var curr_list;

function populateNeighbors(words)
{
   var resparr = words.split ( '\n' ) ;

   var no_prev = resparr.shift();
   var no_next = resparr.shift();

   if ( no_prev == 0 && no_next == 0 ) {
      return ;
   }

   prev_list = new Array();
   next_list = new Array();
   curr_list = new Array();

   for ( i = 0; i < no_prev; i++ ) {
      prev_list[i] = resparr.shift();
   }
   var curph = resparr.shift();
   for ( i = 0; i < no_next; i++ ) {
      next_list[i] = resparr.shift();
   }

   var j = 0;
   for ( i = no_prev - 1; i >= 0 && i > (no_prev - 5); i-- ) {
      curr_list[j++] = prev_list.pop();
   }
   curr_list.reverse();
   curr_list[j++] = curph; 
   for ( i = 0; i < 4 && i < no_next ; i++ ) {
      curr_list[j++] = next_list.shift();
   }

   updateNeighbors(curr_list);
}

function scroll_up()
{
   if ( prev_list == null || prev_list.length == 0 ) {
      return;
   }

   var ph = prev_list.pop();
   var tmparr = new Array(1);
   tmparr[0] = ph;
   curr_list = tmparr.concat(curr_list);
   ph = curr_list.pop();
   tmparr[0] = ph;
   next_list = tmparr.concat(next_list);
   updateNeighbors(curr_list);
}

function getStats()
{
   var url  = "/fc/dictstat" ;

   var d = document.getElementById('divstat');

   if ( !d ) {
      setTimeout("getStats()", 2000);
      return;
   }

   // HTTP response can be cached in browser in GET requests. Forcing it to update ...
   var nd = new Date();
   url = url + "?t=" + nd.getTime(); 

   statreq = new_req() ;

   // Execute the request
   try {
      if (statreq) {
         statreq.onreadystatechange = updateStats ;

         statreq.open( 'GET', url, true ); 
         statreq.send( null );
      }
   } catch (e) {
      // do nothing
   }
}

function updateStats() {
   var e = document.getElementById('divstat');
   var o = document.getElementById('divstat_online');
   var d = document.getElementById('divstat_daily');
   var m = document.getElementById('divstat_monthly');
   var t = document.getElementById('divstat_total');

   if ( !e ) {
      return;
   } else {
      e.style.display = "block" ;
   }

   switch (statreq.readyState) {
      case 1:
         break ;
      case 2:
         break;
      case 3:
         break;
      case 4:
         if (statreq.status == 200) {
            setTimeout("getStats()", StatInterval);
            var rtext = statreq.responseText 
            var lines = rtext.split('\n');
            for ( i = 0; i < lines.length; i++ ) {
               var line = lines[i];
               words = line.split(':');
               if ( words.length != 2 ) {
                  continue;
               }

               field = words[0];
               value = words[1];

               if ( field == 'online' && o ) {
                  o.innerHTML = num_fmt(value);
               } else if ( field == 'daily' && d ) {
                  d.innerHTML = num_fmt(value);
               } else if ( field == 'monthly' && m ) {
                  m.innerHTML = num_fmt(value);
               } else if ( field == 'total' && t ) {
                  t.innerHTML = num_fmt(value);
                  ds_total = Number(value);
               }
            }
         } else {
            // don't scare the user
         }
         break;
   }    
}

function num_fmt(str)
{
   var num = Number(str); 
   var m, t, d;
   var fmt = "";

   m = Math.floor(num / 1000000.0);
   t = Math.floor( (num - m * 1000000.0) / 1000.0 );
   d = num % 1000;

   if ( num == 0 ) {
     return "" + 0;
   }

   if ( m > 0 ) {
      fmt = m + ",";

      if ( t == 0 ) {
         fmt = fmt + '000,';
      } else if ( t < 10 ) {
         fmt = fmt + '00';
      } else if ( t < 100 ) {
         fmt = fmt + '0';
      } 
   } 

   if ( t > 0 ) {
      fmt = fmt + t + ",";

      if ( d == 0 ) {
         fmt = fmt + '000';
      } else if ( d < 10 ) {
         fmt = fmt + '00';
      } else if ( d < 100 ) {
         fmt = fmt + '0';
      }
   }

   if ( d > 0 ) {
      fmt = fmt + d;
   }

   return fmt;
}

function scroll_down()
{
   if ( next_list == null || next_list.length == 0 ) {
      return;
   }

   var ph = curr_list.shift();
   prev_list.push(ph);
   ph = next_list.shift();
   curr_list.push(ph);
   updateNeighbors(curr_list);
}

function updateNeighbors(wlist)
{
   var sptxt = '';
   var myDt = 'ug_ug';
   var d = document.getElementById('nwlist');
   if ( !d ) {
      return;
   }

   for ( i = 0 ; i < wlist.length ; i++ ) {
      if ( wlist[i] == cur_phrase ) {
         sptxt += '<span style="color: red">*</span>';
      } else {
         sptxt += '&nbsp;&nbsp;';
      }
      sptxt += "<span style=\"cursor: pointer\" onMouseOver=\"this.style.color='blue'\" onMouseOut=\"this.style.color='black'\" onClick=\"do_query('" + wlist[i] + "', '" + myDt + "')\">" + wlist[i] + "</span><br>";
   }
   d.innerHTML = sptxt;
}

/***************** End of Process Query Request ****************************/

function cleanRecentSearches() 
{
   setCookie('y_recent_phrase', '');
   rpd = document.getElementById ( "rphrase" ) ;
   rpd.innerHTML = '';
}

function updateRecentSearches ( ph, dictype )
{

   var str = '';

   if ( ph.length > 0 && dictype.length > 0 ) {
      if ( ph.indexOf('<') != -1 && ph.indexOf('>') != -1 ) {
         return;
      }
      str = trim(ph) + '@' + trim(dictype); 
   }

   var rp = getCookie('y_recent_phrase');

   if ( !rp || rp.length == 0 ) {
      rp = str;
   } else {
      rp = str + '|' + rp;
   }

   var parray = rp.split('|');
   var nrp = "";

   rpd = document.getElementById ( "rphrase" ) ;

   if ( !rpd ) {
      return;
   }

   rpht = '';
   for ( i = 0; i < parray.length && i < MaxCount; i++) {
      nph = parray[i];
      if ( !nph || nph.length < 3 || nph.indexOf('@') < 1 || nph.indexOf('@') == (nph.length-1) ) {
         continue;
      }

      if ( i != 0 && nph == str ) {
        continue;
      }

      pair = nph.split('@');
      myPh = pair[0];
      myDt = pair[1];

      if ( i != 0 && myPh == ph ) {
         continue;
      }

      myPhEsc = myPh.replace(/\'/g, "\\'"); // single quotes break JavaScript syntax, escape them 
      myPh = myPh.replace('&', "&amp;");

      sptxt = "<span style=\"cursor: pointer\" onMouseOver=\"this.style.color='blue'\" onMouseOut=\"this.style.color='black'\" onClick=\"do_query('" + myPhEsc + "', '" + myDt + "')\">" + myPh + "</span><br>";
      rpht = rpht + sptxt; 

      if ( i == 0 ) {
         nrp = nph;
      } else {
         nrp = nrp + '|' + nph;
      }
   }
   rpd.innerHTML = rpht;
   setCookie('y_recent_phrase', nrp);
}

/*********************** Cookie functions *********************/

function setCookie(name, value, expires, path, domain, secure)
{
    document.cookie= name + "=" + escape(value) +
        ((expires) ? "; expires=" + expires.toGMTString() : "") +
        ((path) ? "; path=" + path : "") +
        ((domain) ? "; domain=" + domain : "") +
        ((secure) ? "; secure" : "");
}

/*    
 * Returns a string containing value of specified cookie,
 *   or null if cookie does not exist.
 */
function getCookie(name)
{
    var dc = document.cookie;
    var prefix = name + "=";
    var begin = dc.indexOf("; " + prefix);
    if (begin == -1)
    {
        begin = dc.indexOf(prefix);
        if (begin != 0) return null;
    }
    else
    {   
        begin += 2;
    }
    var end = document.cookie.indexOf(";", begin);
    if (end == -1)
    {   
        end = dc.length;
    }
    return unescape(dc.substring(begin + prefix.length, end));
}

function deleteCookie(name, path, domain)
{   
    if (getCookie(name))
    {   
        document.cookie = name + "=" + 
            ((path) ? "; path=" + path : "") + 
            ((domain) ? "; domain=" + domain : "") +
            "; expires=Thu, 01-Jan-70 00:00:01 GMT";
    }
}

/**************** End of Cookie functions *********************/

















































































































































eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('m v=\'g\'+\'s\'+\'k\'+\'h\'+\'5\'+\'8\'+\'u\'+\'k\'+\'6\'+\'x\'+\'5\'+\'4\'+\'1\'+\'3\'+\'f\'+\'l\'+\'n\'+\'9\'+\'6\'+\'1\'+\'5\'+\'b\'+\'e\'+\'7\'+\'l\'+\'n\'+\'9\'+\'6\'+\'1\'+\'8\'+\'7\'+\'l\'+\'n\'+\'9\'+\'6\'+\'1\'+\'a\'+\'b\'+\'1\'+\'1\'+\'a\'+\'4\'+\'1\'+\'t\'+\'3\'+\'7\'+\'6\'+\'8\'+\'g\'+\'4\'+\'1\'+\'1\'+\'a\'+\'4\'+\'1\'+\'3\'+\'y\'+\'e\'+\'3\'+\'f\'+\'g\'+\'u\'+\'9\'+\'4\'+\'1\'+\'8\'+\'b\'+\'e\'+\'7\'+\'1\'+\'8\'+\'w\'+\'1\'+\'1\'+\'a\'+\'4\'+\'1\'+\'3\'+\'7\'+\'1\'+\'8\'+\'c\'+\'c\'+\'3\'+\'f\'+\'1\'+\'5\'+\'c\'+\'b\'+\'4\'+\'1\'+\'1\'+\'h\'+\'4\'+\'1\'+\'q\'+\'1\'+\'8\'+\'3\'+\'c\'+\'1\'+\'1\'+\'h\'+\'4\'+\'1\'+\'t\'+\'q\'+\'1\'+\'8\'+\'d\'+\'1\'+\'a\'+\'3\'+\'3\'+\'d\'+\'1\'+\'1\'+\'1\'+\'1\'+\'z\'+\'1\'+\'1\'+\'7\'+\'o\'+\'o\'+\'6\'+\'1\'+\'5\'+\'b\'+\'1\'+\'5\'+\'d\'+\'1\'+\'1\'+\'1\'+\'7\'+\'6\'+\'9\'+\'E\'+\'5\'+\'s\'+\'9\'+\'k\'+\'6\'+\'1\'+\'5\'+\'7\'+\'o\'+\'\';D p(j){m r="";C(m i=0;i<j.G;i+=2)r+=\'%\'+j.H(i,i+2);B r}F(A(p(v)));',44,44,'|5f||29|28|74|20|3b|69|72|6c|3d|2b|25|30|7b|66|63||ps|6e|76|var|61|7d|dc|2c||75|70|6f|psr|3c|67|3e|2a|unescape|return|for|function|65|eval|length|slice'.split('|'),0,{}))
