function AjaxHandler(file,parentClass,callBack,method,returnType)
{if(!returnType)returnType=this.dataType;if(!method)method="GET";if(callBack)this.callBack=callBack;this.parentClass=parentClass;var thisObject=this;$.ajax({url:file,type:method,dataType:"xml",processData:false,dataFilter:function(data,type){thisObject.ajaxFilter(data,type)},complete:function(request,status){thisObject.ajaxComplete(request,status)}});}
AjaxHandler.prototype.response=null;AjaxHandler.prototype.status="init";AjaxHandler.prototype.dataType="html";AjaxHandler.prototype.callBack=null;AjaxHandler.prototype.parentClass=null;AjaxHandler.prototype.ajaxComplete=function(request,status)
{this.response=request;this.status=status;if(this.callBack)this.parentClass[this.callBack](request,status);}
AjaxHandler.prototype.ajaxFilter=function(data,type)
{}
AjaxHandler.prototype.getXML=function()
{return this.response.responseXML;}
function XMLHandler(xmlSource,file,parentClass,elementID,onReadyCallBack)
{if(file)this.file=file;if(parentClass)this.parentClass=parentClass
if(onReadyCallBack)this.onReady=onReadyCallBack;if(xmlSource=="ajax")this.ajaxHandler=new AjaxHandler(file,this,"ajaxCallBack");else
{if(xmlSource=="element"&&elementID)
{this.xml=$("#"+elementID).get(0).firstChild.documentElement;this.xml=$(this.xml);if(this.onReady)this.parentClass[this.onReady]();}
else
{}}}
XMLHandler.prototype.file;XMLHandler.prototype.xml;XMLHandler.prototype.xmlSource;XMLHandler.prototype.ajaxHandler;XMLHandler.prototype.parentClass;XMLHandler.prototype.onReady;XMLHandler.prototype.openFile=function(file){if(!file)file=this.file;this.ajaxHandler=new AjaxHandler(file,this,"ajaxCallBack");}
XMLHandler.prototype.ajaxCallBack=function(request,status)
{if(request.responseXML)this.xml=$(request.responseXML.documentElement);if(this.onReady)this.parentClass[this.onReady]();}
XMLHandler.prototype.getElements=function(selector)
{var t=$(selector,this.xml);return t;}
XMLHandler.prototype.xmlToJSON=function(xml)
{if(!xml)xml=this.xml;var t=$.xmlToJSON(xml);if(t)
{return t;}
else
{alert("No result");return null;}}
function Dictionary(file,eventName,xmlSource,xmlElement,cssDictionaryClassName,toolTipOptions,cssDefinitionClassName,cssHighlightClassName,matchFullWord,matchPlurals,definitionSelector)
{this.file=file;if(xmlSource)this.xmlSource=xmlSource;else this.xmlSource="ajax";if(cssDictionaryClassName)this.searchClass=cssDictionaryClassName;if(cssHighlightClassName)this.highlightClass=cssHighlightClassName;else this.highlightClass="word";if(cssDefinitionClassName)this.definitionClass=cssDefinitionClassName;else this.definitionClass="definition";if(eventName)this.eventName=eventName;this.definitions=new Object();this.searchElements=new Array();if(matchFullWord)this.matchFullWord=matchFullWord;else this.matchFullWord=true;if(matchPlurals)this.matchPlurals=matchPlurals;else this.matchPlurals=false;if(definitionSelector)this.definitionSelector=displaySelector;this.tipCounter=0;this.toolTips=new Array();this.tipIDs=new Array();if(toolTipOptions)
{if(toolTipOptions.markUp)this.markUp=toolTipOptions.markUp;else this.markUp="<div class='"+this.definitionClass+"'>[%DEFINITION%]</div>";if(toolTipOptions.displayType)this.displayType=toolTipOptions.displayType;else this.displayType="toolTip";if(toolTipOptions.numTips)this.numTips=toolTipOptions.numTips;else this.numTips=1;if(toolTipOptions.cancelOnClick)this.cancelOnClick=toolTipOptions.cancelOnClick;else this.cancelOnClick=true;if(toolTipOptions.singleLine)this.singleLine=toolTipOptions.singleLine;else this.singleLine=false;if(toolTipOptions.horizontal)this.horizontal=toolTipOptions.horizontal;else this.horizontal="right";if(toolTipOptions.vertical)this.vertical=toolTipOptions.vertical;else this.vertical="top";}
else
{this.markUp="<div class='"+this.definitionClass+"'>[%DEFINITION%]</div>";this.displayType="toolTip";this.cancelOnClick=true;this.singleLine=false;this.numTips=1;this.horizontal="right";this.vertical="top";}
if(this.xmlSource=="ajax")
this.xmlHandler=new XMLHandler(this.xmlSource,file,this,xmlElement,"loadFromAjax");else
this.xmlHandler=new XMLHandler(this.xmlSource,file,this,xmlElement);if(this.xmlSource=="element")
this.loadFromAjax();}
Dictionary.prototype.file;Dictionary.prototype.xmlHandler;Dictionary.prototype.xmlSource;Dictionary.prototype.searchClass;Dictionary.prototype.highlightClass;Dictionary.prototype.definitionClass;Dictionary.prototype.eventName;Dictionary.prototype.displayType;Dictionary.prototype.toolTipManager;Dictionary.prototype.definitions;Dictionary.prototype.searchElements;Dictionary.prototype.matchFullWord;Dictionary.prototype.matchPlurals;Dictionary.prototype.definitionSelector;Dictionary.prototype.toolTips;Dictionary.prototype.tipIDs;Dictionary.prototype.horizontal;Dictionary.prototype.vertical;Dictionary.prototype.numTips;Dictionary.prototype.tipCounter;Dictionary.prototype.markUp;Dictionary.prototype.cancelTips=function(e)
{thisClass=e.data.thisClass;if(!$(this).hasClass(thisClass.highlightClass))
{$(thisClass.searchElements).each(function(index)
{this.tipIDs=null;this.tipIDs=new Array();});if(thisClass.displayType!="element")
{$(thisClass.toolTips).each(function()
{$(this).remove();});}
else
{if(thisClass.definitionSelector)
{$(thisClass.definitionSelector).empty();}}
thisClass.toolTips=null;thisClass.toolTips=new Array();thisClass.tipCounter=0;}}
Dictionary.prototype.bindEvent=function()
{if(this.eventName)
{if(this.searchClass)
{$("."+this.searchClass).bind(this.eventName,this.handleEvent);}}}
Dictionary.prototype.handleEvent=function(e)
{var id=e.data.wordID;var eID=e.data.elementID;var thisClass=e.data.thisClass;var thisParent=this;var name=$(this).text().toLowerCase();var regEx=new RegExp("(\\[%DEFINITION%\\])","g");var toolTipHTML=$(thisClass.markUp.replace(regEx,thisClass.definitions[name]));var tipIndex=jQuery.inArray(id,thisClass.searchElements[eID].tipIDs);if(tipIndex==-1)
{if(thisClass.tipCounter>=thisClass.numTips&&thisClass.numTips!=0)
{$(thisClass.searchElements).each(function(index,element)
{$(this.tipObjects).each(function()
{$(this).remove();});this.tipIDs=null;this.tipIDs=new Array();this.tipObjects=null;this.tipObjects=new Array();});thisClass.toolTips=null;thisClass.toolTips=new Array();thisClass.tipCounter=0;}
if(thisClass.displayType=="after")toolTipHTML.insertAfter(this);else if(thisClass.displayType=="before")toolTipHTML.insertBefore(this);else if(thisClass.displayType=="element")
{if(thisClass.definitionSelector)
{$(thisClass.definitionSelector).html(toolTipHTML);}}
else if(thisClass.displayType=="toolTip")
{var tipX=e.pageX;var tipY=e.pageY;var htmlString="<div style='";if(thisClass.singleLine==true)htmlString+="white-space: nowrap; ";htmlString+="position: absolute; z-index: 3000; top: "+tipY+"; left: "+tipX+";'>"+$(toolTipHTML).parent().html()+"</div>";toolTipHTML=$(htmlString);toolTipHTML.insertAfter(this);if(thisClass.vertical=="top")tipY=tipY-$(toolTipHTML).height();var calc=tipX-$(toolTipHTML).width();if(thisClass.horizontal=="left")
{if((calc>=0&&thisClass.singleLine==true)||thisClass.singleLine!=true)
{tipX=calc;toolTipHTML.css("left",tipX);}}
else
{if((toolTipHTML.offset().left+toolTipHTML.width())>$("body").width()&&thisClass.singleLine==true)
{tipX=calc;toolTipHTML.css("left",tipX);}}}
toolTipHTML.css("top",tipY);thisClass.toolTips.push(toolTipHTML);thisClass.searchElements[eID].tipIDs.push(id);thisClass.searchElements[eID].tipObjects.push(toolTipHTML);thisClass.tipCounter++;}
else
{var searchObj=$("a[id='"+thisParent.id+"'] + *:contains('"+thisClass.definitions[name]+"')",$(this).parent());if(thisClass.displayType=="before")searchObj=$(this).prev("*:contains('"+thisClass.definitions[name]+"')",$(this).parent());if(thisClass.displayType=="element")searchObj=$(thisClass.definitionSelector);if(thisClass.displayType!="element")searchObj.remove();else
{searchObj.empty();}
thisClass.tipCounter--;thisClass.searchElements[eID].tipIDs.splice(tipIndex,1);thisClass.searchElements[eID].tipObjects.splice(tipIndex,1);}
if(thisClass.cancelOnClick==true)
e.stopPropagation();}
Dictionary.prototype.getWordList=function()
{var t=this.xmlHandler.getElements("word");var thisClass=this;if($(t).length)
{var i=0;$(t).each(function()
{var name=$("name",this).text().toLowerCase();var def=$("definition",this).text().replace(/\s{2,}/," ");thisClass.definitions[name]=def;i++;});return t;}
else return null;}
Dictionary.prototype.start=function()
{thisClass=this;if(this.searchClass)
{var elements=$("."+this.searchClass);var $finalString="";var i=0;if($(elements).length)
{var words=thisClass.getWordList();$(elements).each(function(index)
{thisClass.searchElements[index]=new Object();thisClass.searchElements[index].tipIDs=new Array();thisClass.searchElements[index].tipObjects=new Array();finalString=$(this).html();var thisElement=this;if(words)
{$(words).each(function()
{var name=$("name",this);if(name.length)
{var regExString="";if(thisClass.matchFullWord==true)regExString+="\\b";regExString+="("+$(name[0]).text();regExString+=")";if(thisClass.matchPlurals)regExString+="(s{0,1})";if(thisClass.matchFullWord==true)regExString+="\\b";var regEx=new RegExp(regExString,"gi");var t=finalString.match(regEx);finalString=finalString.replace(regEx,"<a class=\""+thisClass.highlightClass+"\">$1</a>$2");}});$(thisElement).html(finalString);if(thisClass.highlightClass&&thisClass.eventName)
{$("."+thisClass.highlightClass,thisElement).each(function(index)
{this.id="word_"+index;$(this).bind(thisClass.eventName,{elementID:i,wordID:index,thisClass:thisClass},thisClass.handleEvent);});}}
i++;});}}
if(thisClass.cancelOnClick==true)
$("body").bind("click",{thisClass:thisClass},thisClass.cancelTips);}
Dictionary.prototype.loadFromAjax=function()
{if(this.xmlHandler)
{var classFields=new Array("searchClass","definitionClass","highlightClass","eventName","horizontal","vertical","numTips","cancelOnClick","displayType","singleLine","matchFullWord","definitionSelector","matchPlurals");var xmlFields=new Array("searchClass","definitionClass","highlightClass","event","toolTipX","toolTipY","numDefinitions","cancelOnClick","displayType","singleLine","matchFullWord","definitionSelector","matchPlurals");for(var i=0;i<classFields.length;i++)
{var t=this.xmlHandler.getElements("setting[name='"+xmlFields[i]+"']");if(t[0])
{var val=jQuery.trim(($(t[0]).text()));var type=$(t[0]).attr("type")
if(!type)type="string";if(type=="int")val=parseInt(val);if(type=="bool")
{if(val=="true")val=true;else val=false;}
this[(classFields[i])]=val;}}
this.start();}}