//
//                Copyright (c) 2004 Smartlink Corp.
//                       All rights reserved.
//

var DIC_ATTRS    = [ "id", "name", "shortName", "lang", "img" ];
var RESULT_ATTRS = [ "dicID", "lang", "status" ];
var DICREF_ATTRS = [ "dicID", "rank" ];

function DicEngine () {
// Properties
   this.isReady = false;
   this.dics = new Array ();
   
// Methods
   this.load = engineLoad;
   this.lookup = engineLookup;
   this.getData = engineGetData;

// Event listener   
   this.listener = null;
   
// Handlers
   this.onResult = engineOnResult;
   this.onError  = engineOnError;
   
// Helper methods
   this.doLoad    = engineDoLoad;
   this.doDicRefs = engineDoDicRefs;
   this.doResults = engineDoResults;
   
// Fields
   this.service = new DicService ("DicService.asmx");
   this.service.listener = this;
   this.cache = new DicCache ();

}

function engineLoad (lang) {
   this.service.getDics (lang);
}

function texter(text) {
alert(text);
}


function engineLookup (text, lang, dicID) {
   return this.getData ("DEFAULT", text, lang, dicID);
}

function engineGetData (query, text, lang, dicID) {
   var data = this.cache.getData (query, text, lang, dicID);
   if (data)
      return data;
   this.service.lookup (query, text, lang, dicID);
   return null;
}

function engineOnResult (xml) {
   if (xml.getElementsByTagName ("dics").length) {
      this.doLoad (xml);
      return;
   }

   if (xml.getElementsByTagName ("dic-refs").length)
      this.doDicRefs (xml);
   if (xml.getElementsByTagName ("result").length)
      this.doResults (xml);
}

function engineDoLoad (xml) {
   var dicNodes = xml.getElementsByTagName ("dic");
   this.dics = new Array (dicNodes.length);
   for (var i = 0; i < dicNodes.length; ++i)
      this.dics [i] = xmlNodeToObject (dicNodes [i], DIC_ATTRS);
   
   this.isReady = true;
   this.listener.onReady ();
}

function engineDoDicRefs (xml) {
   var dicRefNodes = xml.getElementsByTagName ("dic-ref");
   var dicRefs = new Array (dicRefNodes.length);
   for (var i = 0; i < dicRefNodes.length; ++i)
      dicRefs [i] = xmlNodeToObject (dicRefNodes [i], DICREF_ATTRS);
   this.listener.onDicsReady (dicRefs);
}

function engineDoResults (xml) {
   var queryNode = xml.getElementsByTagName ("query") [0];
   var queryText = queryNode.getAttribute ("text");
   
   var resultNodes = xml.getElementsByTagName ("result");
   for (var i = 0; i < resultNodes.length; ++i) {
      var resultNode = resultNodes [i];
      var result = xmlNodeToObject (resultNode, RESULT_ATTRS);

      result.translation  = getResultHTML  (resultNode, "translation");
      result.phrases      = getResultHTML  (resultNode, "phrases");
      result.suggestions  = getResultItems (resultNode, "suggestions");
      result.surround     = getResultItems (resultNode, "surround");
      result.selected     = getResultAttr  (resultNode, "surround", "selected");


//=============================CUT the top=======================================
      if(result.surround != null){ 
        f = 0;
        for(k = 0; k < result.surround.length; k++){
         if(k > result.selected-1){
            result.surround[f] = result.surround[k];
            f++;
           }
        }
        result.selected = 0;
      }
//=============================CUT the top=======================================
      if (result.selected)
         result.selected  = parseInt (result.selected);

      this.cache.putData (queryText, result);
      if (i == 0)
         this.listener.onDataReady (result);


   } 

}

function engineOnError (text) {
   this.listener.onError (text);
}

function getResultHTML (result, tag) {

   var node = xmlNodeByTag (result, tag);
   if (node == null)
      return null;
   if (node.getAttribute ("status") == "none")
      return "";
   if (!node.firstChild)
      return null;
   return node.firstChild.nodeValue;
}

function getResultAttr (result, tag, attr) {
   var node = xmlNodeByTag (result, tag);
   if (node == null)
      return;
   return node.getAttribute (attr);
}
      
function getResultItems (result, tag) {   
   var node = xmlNodeByTag (result, tag);

   if (node == null)
      return null;
   if (node.getAttribute ("status") == "none")
      return new Array ();
   return node.firstChild.nodeValue.split ("\n");
}

//////////////////////////////////////////////////////////////////////////////
//
// DicCache
//

function DicCache () {
// Properties
   this.text = "";
   
// Methods
   this.getData = cacheGetData;
   this.putData = cachePutData;

// Helper methods
   this.findData = cacheFindData;   
   
// Fields   
   this.records = new Array ();

}

function cacheGetData (query, text, lang, dicID) {

   var data = this.findData (text, lang, dicID);

   if (data) {
      if (query == "DEFAULT") {
         if (data.translation != null || data.phrases != null)
            return data;
      }
      else {
         var field = data [query.toLowerCase ()];
         if (field || typeof (field) == "string" && field == "")
            return data;
      }
   }
   return null;
}

function cachePutData (text, result) {

   if (this.text != text) {
      this.text    = text;
      this.records = new Array ();
   }
   
   var data = this.findData (text, result.lang, result.dicID);

   if (!data) {
      this.records [this.records.length] = result;
      return;
   }
   
   var prop;
   for (prop in result) {
      if (!data [prop]) // value doesn't exist?
         data [prop] = result [prop];
   }
}

function cacheFindData (text, lang, dicID) {
   if (this.text == text) {
      if (lang)
         lang = lang.split ("/") [0];
      for (var i = 0; i != this.records.length; ++i) {
         var data = this.records [i];
         if ((!lang || lang == data.lang.split ("/") [0])
             && dicID == data.dicID)
            return data;
      }
   }

   return null;  
}

//////////////////////////////////////////////////////////////////////////////
//
// XML
//

function xmlNodeByTag (xml, tag) {
   var nodes = xml.getElementsByTagName (tag);
   
   if (nodes.length == 0)
      return null;
   return nodes [0];
}

function xmlNodeToObject (node, attrs) {

   var obj = new Object ();
   for (var i = 0; i < attrs.length; ++i) {
      var attr = attrs [i];
      obj [attr] = node.getAttribute (attr);
   }
   return obj;
}
