tangler.manager.TopicState=function(){var _3ae=function(){this.groupId=0;this.topicId=0;this.authorId=0;this.topicUrl=null;this.messageCount=0;this.isTopicWatched=false;_3ae.superclass.constructor.call(this);};Ext.extend(_3ae,Ext.util.Observable,{setGroupId:function(_3af){this.groupId=_3af;},getGroupId:function(){return this.groupId;},getTopicUrl:function(){return "/conversations/"+this.topicId;},setMessageCount:function(_3b0){this.messageCount=_3b0;},getMessageCount:function(){return this.messageCount;},setAuthorId:function(aId){this.authorId=aId;},getAuthorId:function(){return this.authorId;},setTopicId:function(tId){this.topicId=tId;},getTopicId:function(){return this.topicId;},setTopicWatched:function(_3b3){this.isTopicWatched=_3b3;},getTopicWatched:function(){return this.isTopicWatched;}});return new _3ae();}();tangler.manager.AuthorState=function(){var _3b4=function(){this.delayedTask=null;this.focusedAuthorId=0;this.focusedAuthorScreenName="";this.addEvents({"authorFocused":true,"authorUnfocused":true});_3b4.superclass.constructor.call(this);};Ext.extend(_3b4,Ext.util.Observable,{setFocusAuthor:function(id,ele,_3b7){this.focusedAuthorId=id;if(this.focusedAuthorId!=0){if(this.delayedTask==null){this.delayedTask=new Ext.util.DelayedTask();}this.delayedTask.delay(700,function(){this.fireEvent("authorFocused",id,ele,_3b7);},this);}else{if(this.delayedTask!=null){this.delayedTask.cancel();}this.fireEvent("authorUnfocused");}},getFocusAuthorId:function(){return this.focusedAuthorId;},setFocusAuthorScreenName:function(_3b8){if(_3b8!=null&&_3b8!=""){this.focusedAuthorScreenName=_3b8;}},getFocusAuthorScreenName:function(){return this.focusedAuthorScreenName;}});return new _3b4();}();tangler.manager.Message=function(_3b9,_3ba){this._inputId=_3b9;this._editor=null;this._submitFunction=null;this._isChat=tangler.util.Options.getOptionalArgument("isChat",_3ba,false);this._setContent=null;};tangler.manager.Message.prototype={setSubmitFunction:function(_3bb){this._submitFunction=_3bb;},toggleChatMode:function(_3bc){this._isChat=_3bc;if(this._editor){this._editor.toggleChatMode(_3bc);}},showInput:function(_3bd){if(!this._editor){try{this._editor=new tinymce.Editor(this._inputId,{mode:"textareas",theme:"advanced",plugins:"media,inlinepopups",content_css:"css/content.css",theme_advanced_toolbar_location:"top",theme_advanced_toolbar_align:"left",theme_advanced_buttons1:"bold,italic,underline,strikethrough,forecolor,separator,bullist,numlist,link,separator,image,media,cemoties",theme_advanced_buttons2:"",theme_advanced_buttons3:"",theme_advanced_more_colors:0});this._editor.onKeyPress.add(function(ed,e){if(!e.shiftKey&&e.keyCode==13){var _3c0=true;_3c0=ed.editorId=="editor"?true:false;if(_3c0){var _3c1=ed.selection.getNode();if(_3c1.tagName.toUpperCase()=="LI"){return;}_self.submitMessage();setTimeout(function(){_self.resetEditor();},10);}return;}});this._editor.onPostRender.add(function(ed){if(tangler.info.Session.getSecurity().isAuthenticated()||tangler.info.Session.getSecurity().isAnonymousPoster()){setTimeout(function(){ed.focus();},200);}});this._editor.render();}catch(e){if(tangler.util.Element.getEl(this._inputId)==null){var _3c3=tangler.util.Element.createNode("textarea",{attributes:[["id",this._inputId]]});document.appendChild(_3c3);}this._editor=new tinymce.Editor(this._inputId,{mode:"textareas",theme:"advanced",plugins:"media,inlinepopups",content_css:"css/content.css",theme_advanced_toolbar_location:"top",theme_advanced_toolbar_align:"left",theme_advanced_buttons1:"bold,italic,underline,strikethrough,forecolor,separator,bullist,numlist,link,separator,image,media,cemoties",theme_advanced_buttons2:"",theme_advanced_buttons3:"",theme_advanced_more_colors:0});this._editor.onKeyUp.add(function(ed,e){if(!e.shiftKey&&e.keyCode==13){var _3c6=true;_3c6=ed.editorId=="editor"?true:false;if(_3c6){var _3c7=ed.selection.getNode();if(_3c7.tagName.toUpperCase()=="LI"){return;}_self.submitMessage();setTimeout(function(){_self.resetEditor();},10);}return;}});this._editor.onPostRender.add(function(ed){if(tangler.info.Session.getSecurity().isAuthenticated()||tangler.info.Session.getSecurity().isAnonymousPoster()){setTimeout(function(){ed.focus();},200);}});this._editor.render();}if(this._setContent){this._editor.selectAll();this._editor.insertHTML(this._setContent);this._setContent=null;}}},submit:function(){if(this._editor){this._submitFunction();}},hideInput:function(_3c9){if(this._editor){this._editor.hide();}},resetInput:function(){if(this._editor){this._editor.setContent("");}},focusInput:function(){if(tangler.info.Session.getSecurity().isAuthenticated()||tangler.info.Session.getSecurity().isAnonymousPoster()){setTimeout(this.focusInputCallback(this),200);}else{setTimeout(this.blurInputCallback(this),200);}},focus:function(){if(_self._editor){_self._editor.focus();}},blurInputCallback:function(_3ca){return function(){window.focus();if(_3ca._editor){_3ca._editor.blur();}};},focusInputCallback:function(_3cb){return function(){if(_3cb._editor){_3cb._editor.focus();}};},setInputContent:function(_3cc){if(this._editor){this._editor.setContent(_3cc);}else{this._setContent=_3cc;}},getInputContent:function(){if(this._editor){return this._editor.getContent();}else{return null;}}};tangler.manager.QueProcessor=function(){var _3cd=new Array();var _3ce=false;var _3cf=true;var _3d0=false;var _3d1=50;return {isInited:function(){return _3d0;},init:function(){_3d0=true;setInterval(this.processQueue,_3d1);},queue:function(msg){_3cd.push(msg);},priorityQueue:function(msg){_3cd.unshift(msg);},processQueue:function(){if(!_3cf){return;}_3cf=false;try{var _3d4=_3cd.shift();if(_3d4){var _3d5=_3d4.detail.globalId;_self.onMessagEventProxy(_3d4);if(typeof (_3d4.undelivered)!="undefined"&&_3d4.undelivered==true){_self.markMessageUndelivered(_3d4.detail.globalId);}else{if(typeof (_3d4.undelivered)!="undefined"&&_3d4.undelivered==false){MessageHandler.createMessage(_3d4.detail.globalTopicId,_3d4.detail.quoteMessage,_3d4.detail.parentMessageId,{callback:function(msg){_self._updateCreatedMessage(msg,_3d5);},errorHandler:_self._createMessageFailed});}}}}catch(e){try{console.log("Error occured while processing queue ");}catch(ex){}}_3cf=true;}};};tangler.manager.TopicMessageList=function(){var _3d7=tangler.manager.AuthorState;var _3d8=tangler.manager.TopicState;var _3d9=tangler.view.TopicLifecycleConvertor;var _3da=tangler.manager.Comms;var _3db=null;var _3dc=false;var _3dd=null;var _3de=null;var _3df=null;var _3e0=0;var _3e1=0;var _3e2=0;var _3e3=null;var _3e4=null;var _3e5=false;var _3e6;var _3e7=null;var _3e8=null;var _3e9=0;var _3ea="";var _3eb=30000;var _3ec="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";var _3ed=1;var _3ee=true;var _3ef=500;var _3f0=new Date().getTime();var _3f1=0;var _3f2=new tangler.manager.QueProcessor();var _3f3=0;var _3f4=0;var _3f5="";var _3f6;var _3f7=false;var _3f8=new Ext.Template("<div class=\"authorInfo\">","   <div class=\"avatar\"><img src=\"{authorAvatarUrl}\"/></div>","   <div class=\"details\">","      <h4>{authorScreenName}</h4>","      <div id=\"authorFullname\" class=\"subDetails\">{authorFullname}</div>","      <div id=\"authorLocation\" class=\"subDetails\">{authorLocation}</div>","      <div id=\"me\" class=\"me\">me</div>","      <div id=\"authorActions\" class=\"subDetails\">","         <a href=\"{profileUrl}\" id=\"profileLink\">View Profile</a> <span id=\"followOpt\">| <a href=\"{interactionUrl}\" id=\"followUserAuthorPopup\">{interactionType}</a> </span>","      </div>","\t\t{banButton}","      </div>","   </div>","</div>");var _3f9=function(){_3f9.superclass.constructor.call(this);_self=this;};Ext.extend(_3f9,Ext.util.Observable,{init:function(_3fa){if(_3e5){return;}_3de=new tangler.manager.Message("editor",{isChat:false});_3de.setSubmitFunction(_self._sendMessage);_3de.showInput({simpleButtons:false});_3df=new tangler.manager.Message("editMessageInput");_3d7.on("authorFocused",_self._onAuthorFocused);_3d7.on("authorUnfocused",_self._onAuthorUnfocused);_3e6=tangler.util.Options.getOptionalArgument("messagesDiv",_3fa,"messages");if(tangler.info.Session.getSecurity().isAnonymousPoster()){tangler.util.Element.getEl("messageEditorOverlay").hide();}var _3fb=tangler.util.Options.getOptionalArgument("topicId",_3fa,0);var _3fc=tangler.util.Options.getOptionalArgument("topicCreatorId",_3fa,0);var _3fd=tangler.util.Options.getOptionalArgument("groupId",_3fa,0);var _3fe=tangler.util.Options.getOptionalArgument("isWatched",_3fa,false);var _3ff=tangler.util.Options.getOptionalArgument("messageCount",_3fa,0);_3d8.setTopicId(_3fb);_3d8.setAuthorId(_3fc);_3d8.setGroupId(_3fd);_3d8.setTopicWatched(_3fe);_3d8.setMessageCount(_3ff);if(!_3f2.isInited()){_3f2.init();}return;},getEditor:function(){return _3de;},getMessages:function(_400){tangler.util.Element.removeChildNodes(_3e6);tangler.util.Element.getEl(_3e6).removeClass("hide");tangler.util.Element.getEl(_3e6).dom.appendChild(tangler.util.Element.createSmallLoadingElement());MessageHandler.getMessagesAndLastRead(_400,{callback:_self._getMessagesAndLastReadCallback,errorHandler:_self._getMessagesAndLastReadError,timeout:_3eb});},getMessagesAndScroll:function(_401,_402){_3e0=_402;this.getMessages(_401);},reset:function(){tangler.cache.CacheManager.clearMessageCache();_3e8=null;_3e9=0;_3e1=0;tangler.info.Session.setMessageLastViewedDate(0);},setLastRead:function(_403){_3e8=_403;},onMessageEvent:function(_404){_3f2.queue(_404);},onBannedMessageEvent:function(_405){alert("You are banned from this topic!");},onMessagEventProxy:function(_406){var _407=tangler.util.Element.getEl("message-"+_406.detail.globalId);if(_407==null){_self._buildMessage(_406,{lastRead:new Date(),ignoreLastRead:true,doSort:true});if(_406.permissions.quotable!=null){if(!tangler.info.Page.isFocused()){tangler.util.Functions.attractUser(_406);}}if(tangler.util.Helper.canScroll("messageViewPort","messages")){tangler.util.Helper.scrollElementToEnd("messageViewPort");}}else{var msg=new tangler.domain.MessageElement(_406.detail,_406.permissions,_406.auditHistory);msg.updateElement();if(msg.checkAndRemoveMessageAuthor(_3e2)){_self._updatePreviousAuthorDetails();}delete msg;}var _409=tangler.util.formatter.formatDateTime(_406.detail.lastModified);if(_409>tangler.info.Session.getMessageLastViewedDate()){tangler.info.Session.setMessageLastViewedDate(_409);_self._sendTopicLastMessageViewed(tangler.info.Session.getTopicId());}},submitMessage:function(){_3f7=false;_3de.submit();_3de.focusInput();},resetEditor:function(){_3de.setInputContent("");_3de.focus();},_updatePreviousAuthorDetails:function(){var _40a=tangler.util.Element.getEl("messages").select("div.author").elements;if(_40a.length>0){var _40b=_40a[_40a.length-1];var _40c=_40b.id;var _40d=_40c.split("@")[1].split("|")[0];var _40e=parseInt(_40c.split("@")[1].split("|")[1]);if(_3e9!=_40e&&_3ea!=_40d){_3e9=_40e;_3ea=_40d;}}else{_3e9=0;_3ea="";}},_sendMessage:function(){if(!_3f7){messagePending=_3de.getInputContent().trim();_3f4=0;_3f5="";}else{messagePending=_3df.getInputContent().trim();}if(messagePending.indexOf("__RP_Callback_Helper(str,")!=-1){Ext.MessageBox.show({title:"Message Warning",msg:"You appear to have Real Player installed and it is inserting some text into your comment:<br>"+"<p>&lt;script type=\"text/javascript\"&gt;&lt;!-- function __RP_Callback_Helper...&lt;/script&gt;</p><br>"+"Press 'Cancel' and remove the Real Player Browser Record Plugin to prevent this or 'OK' to continue. \"",buttons:Ext.MessageBox.OKCANCEL,fn:function(btn,text){if(btn=="ok"){_self._processSendingMessage(messagePending);}else{return;}}});return;}else{_self._processSendingMessage(messagePending);}},_editMessage:function(){var _411=_3df.getInputContent().trim();if(_self._isMessageEmpty(_411)){_3df.resetInput();return;}_3e3.hide();if(_3e1!=null&&_3e1!=0){var _412="";var _413=document.getElementById("quoteMessage-"+_3e1);if(!tangler.util.StringUtil.isEmpty(_413)){_412=tangler.util.StringUtil.getTextAndRemoveHtmlTags(_413.innerHTML);_412="<quote>"+_412+"</quote>";}if(_411.length>1000){if(_3e7==null){_3e7=new tangler.widget.DialogWrapper("sending-dlg",{width:150,height:105});}_3e7.showDialog();}_411=_411.replace(/<br \/>&nbsp;<\/p>/g,"</p>");_411=_411.replace(/<br\/>&nbsp;<\/p>/g,"</p>");_411=_411.replace(/<br>&nbsp;<\/p>/g,"</p>");MessageHandler.modifyMessage(_3e1,_412+_411,{callback:_self._modifyMessageCallback,errorHandler:_self._modifyMessageError});}},_modifyMessageCallback:function(_414){if(_3e7!=null&&_3e7.isVisible()){_3e7.hide();}_3e1=0;var _415=new tangler.domain.MessageElement(_414.detail,_414.permissions,_414.auditHistory);var _416={};_416=_self._setCreateMessageEventArguments(_416,_414);_415.updateElement(_416);delete _415;},_modifyMessageError:function(_417){if(_3e7!=null&&_3e7.isVisible()){_3e7.hide();}alert("Failed to edit message");},_processSendingMessage:function(_418){if(_self._isMessageEmpty(_418)){if(_3f7){_3df.resetInput();return;}else{_3de.resetInput();return;}}var _419=tangler.info.Session.getTopicId();_3de.resetInput();if(_418.length>1000){if(_3e7==null){_3e7=new tangler.widget.DialogWrapper("sending-dlg",{width:100,height:100});}_3e7.showDialog();}_418=_418.replace(/%25/g,"%");_418=_418.replace(/<br \/>&nbsp;<\/p>/g,"</p>");_418=_418.replace(/<br\/>&nbsp;<\/p>/g,"</p>");_418=_418.replace(/<br>&nbsp;<\/p>/g,"</p>");var _now=new Date();var _41b=null;var _41c=tangler.info.Session.getSecurity().isAnonymousPoster();if(_41c){_41b={anonymousScreenName:tangler.info.Session.getUser(),remoteIp:"127.0.0.1"};}var _41d=tangler.info.Session.getAvatar();var _41e=Math.random().toString().substring(2);var _41f={undelivered:false,auditHistory:null,permissions:{deletable:false,modifiable:false},detail:{showAttribs:false,anonymousDetail:_41b,author:{anonymous:_41c,avatar:_41d,created:_now,lastModified:_now,fullName:"",screenName:_41c?"anonymousUser":tangler.info.Session.getUser(),globalId:_41c?1:tangler.info.Session.getUserId()},body:_3f5+_418,created:_now,lastModified:_now,globalId:_41e,globalTopicId:_419,parentMessageId:_3f4,quoteMessage:_3f5+_418}};_thisMessageTime=new Date().getTime();if(_thisMessageTime-_3f0<=_3ef){_3f0=new Date().getTime();_3f1++;}else{_3f1=0;}if(_3f1>5&&_thisMessageTime-_3f0<=_3ef){_41f.undelivered=true;}_3f2.priorityQueue(_41f);_3f0=new Date().getTime();},markMessageUndelivered:function(_420){var _421=Ext.get("message-"+_420);if(_421){_421.addClass("undeliverd");var _422=_421.select("span.msgOptions").elements;if(_422!=null&&_422.length>0){var _423=_422[0];var _424={};_424=_self._setCreateRepostEventArguments(_424,_420);var _425=new tangler.domain.MessageElement().createMessageRepostOption(_424);_423.appendChild(_425);}}},_onAuthorFocused:function(_426,_427,_428){if(_3db==null){_3db=new tangler.widget.DialogWrapper("author-dlg",{autoHeight:true,width:240,resizable:false,draggable:true,modal:false,shadow:false});_3db.getDialog().getEl().on("mouseover",_self._onAuthorDialogMouseOver);_3db.getDialog().getEl().on("mouseout",_self._onAuthorDialogMouseOut);}tangler.util.Element.removeChildNodes("messageAuthorDetails");tangler.util.Element.getEl("messageAuthorDetails").appendChild(tangler.util.Element.createLoadingElement());if(_426==-1&&_428!=null){_self._getanonymousProfileCallback(_428,_427);}else{DWRUserHandler.getUserProfile(_426,{callback:function(_429){_self._getUserProfileCallback(_429,_427);},errorHandler:function(_42a){alert(_42a);}});}_3db.showDialog({"element":tangler.util.Element.getEl(_427)});},_onAuthorUnfocused:function(){if(_3dd==null){_3dd=new Ext.util.DelayedTask();}_3dd.delay(500,function(){if(_3db&&!_3dc){_3db.hide();}},this);},_onAuthorDialogMouseOver:function(){_3dc=true;},_onAuthorDialogMouseOut:function(){if(_3dc){_3dc=false;_self._onAuthorUnfocused();}},_removeMessageCallback:function(_42b){var _42c=new tangler.domain.MessageElement(_42b.detail,_42b.permissions,_42b.auditHistory);_42c.removeElement();var _42d=document.getElementById("quoteMessage-"+_42b.detail.globalId);if(_42d!=null){_42d.parentNode.removeChild(_42d);}if(_42c.checkAndRemoveMessageAuthor(_3e2)){_self._updatePreviousAuthorDetails();}delete _42c;_3de.focusInput();},_onRepostMessage:function(_42e){return function(){var _42f=Ext.get("message-"+_42e);var _430=tangler.cache.CacheManager.getMessage(_42e);if(_42f!=null&&_430!=null){_42f.dom.parentNode.removeChild(_42f.dom);_self._processSendingMessage(_430.body);}};},_onEditMessage:function(_431){return function(){var _432=tangler.util.Element.getEl("message-"+_431);var _433=tangler.util.Element.getElementsByClassName(_432,"div",["msgBody"])[0];var _434=false;if(_3e3==null){_3e3=new tangler.widget.DialogWrapper("editMessage-dlg",{width:485,height:290,resizable:false,draggable:false,acceptLabel:"Send",acceptFunction:function(){if(_3df){_3df.submit();}_3e3.hide();},declineLabel:"Cancel",declineFunction:function(){_3e3.hide();}});_3e3.addListener("beforeHide",function(_435){_3df.resetInput();_3df.hideInput();_3df.focusInput();});Ext.get("editMessageInput").dom.value=_433.innerHTML;_434=true;_3df.showInput({simpleButtons:tangler.info.Page.isEmbed()});}_3df.setSubmitFunction(_self._editMessage);if(_3e3.isVisible()){return;}var _436=document.getElementById("quoteMessage-"+_431);var _437=null;var _438=null;if(!tangler.util.StringUtil.isEmpty(_436)){var _439="";_439=tangler.util.StringUtil.getTextAndRemoveHtmlTags(_436.innerHTML);var msg="";if(!tangler.util.StringUtil.isEmpty(_439)){_439=_439.replace(/"/g,"");if(_439.length>80){msg=_439.substring(_439.indexOf(":")+1,80)+"...";}else{msg=_439.substring(_439.indexOf(":")+1,_439.length)+"...";}_437=_439.substring(0,_439.indexOf(":"));_438=" <p id=\"quoteMsg\" class=\"p\"> <strong>"+_437+" :</strong><br> "+msg+" </p>";}}_3e3.setTitle("Edit message");var _43b=Ext.get("quoteMessage-div");if(_438==null){_43b.dom.style.display="none";}else{_43b.dom.innerHTML=_438;_43b.dom.style.display="block";}_3e3.showDialog();_3df._editor.show();if(!_434){_3df.setInputContent(_433.innerHTML);}_3e1=_431;};},_onClickQuoteButton:function(_43c){return function(){if(_3e3==null){_3e3=new tangler.widget.DialogWrapper("editMessage-dlg",{height:290,resizable:false,draggable:false,acceptLabel:"Send",acceptFunction:function(){if(_3df){_3f7=true;_3df.submit();_3e3.hide();}},declineLabel:"Cancel",declineFunction:function(){_3f7=false;_3e3.hide();}});_3df.showInput({simpleButtons:false});}_3df.setSubmitFunction(_self._sendMessage);var _43d=tangler.cache.CacheManager.getMessage(_43c);_3f4=_43c;var _43e=_43d.body;_43e=tangler.util.StringUtil.getTextAndRemoveHtmlTags(_43e);var _43f=null;if(!tangler.util.StringUtil.isEmpty(_43e)){if(_43e.length>100){_43e=_43e.substring(0,100)+"...";}if(_43d.author.anonymous){_43f=_43d.anonymousDetail.anonymousScreenName;_3f5="<quote>"+_43d.anonymousDetail.anonymousScreenName+" said : \""+_43e+"\"</quote>";}else{_43f=_43d.author.screenName;_3f5="<quote>"+_43d.author.screenName+" said : \""+_43e+"\"</quote>";}if(_43e.length>50){_43e=_43e.substring(0,50)+"...";}else{_43e=_43e+"...";}}_3e3.addListener("beforeHide",function(_440){_3df.resetInput();_3df.hideInput();_3df.focusInput();});_3e3.setTitle("Quote message");if(_3e3.isVisible()){return;}_3e3.showDialog();var _441=Ext.get("quoteMessage-div");var _442=" <p id=\"quoteMsg\" class=\"p\"> <strong>"+_43f+" said :</strong><br> "+_43e+" </p>";_441.dom.innerHTML=_442;_441.dom.style.display="block";_3df._editor.show();};},_onDeleteMessage:function(_443){return function(){if(_3e4==null){_3e4=new tangler.widget.DialogWrapper("deleteMessage-dlg",{minHeight:100,width:330,height:130,draggable:false,resizable:false,acceptLabel:"Yes",defaultFocus:"Yes",acceptFunction:function(){_3e4.hide();if(_3e2!=null&&_3e2!=0){MessageHandler.removeMessage(_3e2,{callback:_self._removeMessageCallback,errorHandler:function(_444){alert("Failed to remove message");_3de.focusInput();}});}},declineLabel:"No",declineFunction:function(){_3e4.hide();_3de.focusInput();}});}if(_3e4.isVisible()){return;}var _445=tangler.util.Element.getEl("message-"+_443);var _446=tangler.util.Element.getElementsByClassName(_445,"div",["msgBody"])[0];_3e2=_443;_3e4.showDialog();};},_highlight:function(_447){return function(){tangler.util.Element.getEl("message-"+_447).dom.className+=" highlight";};},_removeHighlight:function(_448){return function(){tangler.util.Element.getEl("message-"+_448).dom.className=tangler.util.Element.getEl("message-"+_448).dom.className.replace(new RegExp(" highlight\\b"),"");};},_buildMessage:function(_449,_44a){var _44b=tangler.info.Session.getMessageLastViewedDate();var utc=_449.detail.created.toUTCString();var _44d=new Date();var _44e=tangler.util.Options.getOptionalArgument("lastRead",_44a,0);var dom=tangler.util.Options.getOptionalArgument("fragment",_44a,tangler.util.Element.getEl("messages"));var _450=tangler.util.Options.getOptionalArgument("doSort",_44a,false);if(_449.detail.globalTopicId==tangler.info.Session.getTopicId()){if(_449.permissions.quotable){var _451=tangler.util.StringUtil.getQuoteMessageOrMessageBody(_449.detail.body,false);var _452=tangler.util.StringUtil.getTextAndRemoveHtmlTags(_451);if(_452==null||_452==""){_449.permissions.quotable=false;}}var msg=new tangler.domain.MessageElement(_449.detail,_449.permissions,_449.auditHistory);_44a=_self._setCreateMessageEventArguments(_44a?_44a:{},_449);var _454=msg.createMessage(dom,_44a);_3e9=_449.detail.author.globalId;_3ea=_449.detail.author.screenName;if(_449.detail.author.screenName=="anonymousUser"){_3ea=_449.detail.anonymousDetail.anonymousScreenName;}delete msg;}},_buildMessages:function(_455,_456){var _457=tangler.util.formatter.formatDateTime(_3e8);var _458=0;for(var i=0;i<_455.length;++i){if(_455[i].auditHistory&&_455[i].auditHistory.operation=="DELETE"){continue;}_self._buildMessage(_455[i],_456);var _45a=tangler.util.formatter.formatDateTime(_455[i].detail.lastModified);if((_457==0&&i==0)||(_45a<_457)){_458=_455[i].detail.globalId;}if(_45a>tangler.info.Session.getMessageLastViewedDate()){tangler.info.Session.setMessageLastViewedDate(_45a);}}return _458;},_buildOlderMessage:function(_45b,_45c,_45d){var _45e=tangler.info.Session.getMessageLastViewedDate();var utc=_45b.detail.created.toUTCString();var _460=new Date();var _461=tangler.util.Options.getOptionalArgument("lastRead",_45c,0);var dom=tangler.util.Options.getOptionalArgument("fragment",_45c,tangler.util.Element.getEl("messages"));var _463=tangler.util.Options.getOptionalArgument("doSort",_45c,false);if(_45b.detail.globalTopicId==tangler.info.Session.getTopicId()){if(_45b.permissions.quotable){var _464=tangler.util.StringUtil.getQuoteMessageOrMessageBody(_45b.detail.body,false);var _465=tangler.util.StringUtil.getTextAndRemoveHtmlTags(_464);if(_465==null||_465==""){_45b.permissions.quotable=false;}}var msg=new tangler.domain.MessageElement(_45b.detail,_45b.permissions,_45b.auditHistory);_45c=_self._setCreateMessageEventArguments(_45c?_45c:{},_45b);var _467=msg.createOlderMessage(dom,_45c,_45d);_3e9=_45b.detail.author.globalId;_3ea=_45b.detail.author.screenName;if(_45b.detail.author.screenName=="anonymousUser"){_3ea=_45b.detail.anonymousDetail.anonymousScreenName;}delete msg;}},_buildOlderMessages:function(_468,_469){var _46a=tangler.util.formatter.formatDateTime(_3e8);var _46b=0;var _46c=0;for(var i=0;i<_468.length;++i){if(_468[i].auditHistory&&_468[i].auditHistory.operation=="DELETE"){_46c--;continue;}_self._buildOlderMessage(_468[i],_469,_46c);_46c++;var _46e=tangler.util.formatter.formatDateTime(_468[i].detail.lastModified);if((_46a==0&&i==0)||(_46e<_46a)){_46b=_468[i].detail.globalId;}if(_46e>tangler.info.Session.getMessageLastViewedDate()){tangler.info.Session.setMessageLastViewedDate(_46e);}}return _46b;},_setCreateMessageEventArguments:function(_46f,_470){_46f.onModifyMouseOver=_self._highlight(_470.detail.globalId);_46f.onModifyMouseOut=_self._removeHighlight(_470.detail.globalId);_46f.onDeleteMouseOver=_self._highlight(_470.detail.globalId);_46f.onDeleteMouseOut=_self._removeHighlight(_470.detail.globalId);_46f.onDeleteClick=_self._onDeleteMessage(_470.detail.globalId);_46f.onEditMouseOver=_self._highlight(_470.detail.globalId);_46f.onEditMouseOut=_self._removeHighlight(_470.detail.globalId);_46f.onEditClick=_self._onEditMessage(_470.detail.globalId);_46f.onQuoteClick=_self._onClickQuoteButton(_470.detail.globalId);_46f.onQuoteMouseOver=_self._highlight(_470.detail.globalId);_46f.onQuoteMouseOut=_self._removeHighlight(_470.detail.globalId);_46f.onTimespanMouseOver=_self._highlight(_470.detail.globalId);_46f.onTimespanMouseOut=_self._removeHighlight(_470.detail.globalId);return _46f;},_setCreateRepostEventArguments:function(_471,_472){_471.onRepostMouseOver=_self._highlight(_472);_471.onRepostMouseOut=_self._removeHighlight(_472);_471.onRepostClick=_self._onRepostMessage(_472);return _471;},_isMessageEmpty:function(_473){var _474=_473.replace(/&nbsp;/g,"");_474=_474.replace(/<p>/g,"");_474=_474.replace(/<\/p>/g,"");_474=_474.replace(/<ul>/g,"");_474=_474.replace(/<\/ul>/g,"");_474=_474.replace(/<ol>/g,"");_474=_474.replace(/<\/ol>/g,"");_474=_474.replace(/<br \/>/g,"");_474=_474.replace(/<strong>/g,"");_474=_474.replace(/<\/strong>/g,"");_474=_474.replace(/<em>/g,"");_474=_474.replace(/<\/em>/g,"");_474=_474.replace(/<u>/g,"");_474=_474.replace(/<\/u>/g,"");_474=_474.replace(/<del>/g,"");_474=_474.replace(/<\/del>/g,"");if(_474.trim().length==0){return true;}if(_474.trim().length==1&&_474.charCodeAt(0)==160){return true;}return false;},_getMessagesAndLastReadError:function(_475){_messageListLoaded=false;tangler.util.Element.getEl(_3e6).dom.innerHTML="";var li=tangler.util.Element.createNode("li",{attributes:[["class","error"]],children:[document.createTextNode("An error occurred while retrieving messages."+_475),tangler.util.Element.createNode("br")]});li.className="error";tangler.util.Element.getEl(_3e6).dom.appendChild(li);var _477=tangler.util.Element.createNode("a",{attributes:[["href","#"]],children:[document.createTextNode("Try again")]});li.appendChild(_477);},heartbeatCallback:function(){},onBeforeHeartbeat:function(){},_getMessagesAndLastReadCallback:function(_478){tangler.util.Element.removeChildNodes(_3e6);tangler.cache.CacheManager.clearMessageCache();_3e8=_478.lastRead;var _479=50;var _47a=_478.totalAndReadMessageCountReport.totalMessageCount;var _47b=_478.totalAndReadMessageCountReport.globalParentId;if(_47a>_479){var _47c=Ext.get("viewOldMessageButton");_47c.dom.style.display="block";_47c.on("click",_self._viewOlderMessages);_3f3=_479;}_self._showTopicHeader(_478.topic);_3d9.setTopicLifecycle(_478.topic);var _47d=!tangler.info.Session.getSecurity().isAuthenticated();var _47e=_self._buildMessages(_478.messages,{lastRead:_3e8,ignoreLastRead:_47d});if(_3e0!=0&&tangler.util.Element.getEl("message-"+_3e0)){tangler.util.Helper.scrollElementTo("message-"+_3e0,"messageViewPort");tangler.util.Element.getEl("message-"+_3e0).highlight("fffbb4",{easing:"easeIn",duration:10});}else{if(_3e0!=0&&tangler.util.Element.getEl("quoteMessage-"+_3e0)){tangler.util.Helper.scrollElementTo("quoteMessage-"+_3e0,"messageViewPort");tangler.util.Element.getEl("quoteMessage-"+_3e0).highlight("fffbb4",{easing:"easeIn",duration:10});}else{tangler.util.Helper.scrollElementToEnd("messageViewPort");}}if(_478.messages.length>0){var _47f=tangler.info.Session.getMessageLastViewedDate();var _480=tangler.util.formatter.formatDateTime(_3e8);if(_480==0||(_480!=_47f)){_self._sendTopicLastMessageViewed(tangler.info.Session.getTopicId());}}if(_478.messages.length==0){var now=new Date();var _482=Date.UTC(now.getFullYear(),now.getMonth(),now.getDay(),now.getHours(),now.getMinutes(),now.getSeconds(),0);if(_482!=null&&tangler.info.Session.getSecurity().isAuthenticated()){DWRTopicHandler.setTopicLastMessageViewed(tangler.info.Session.getTopicId(),_482);}}var _483=_478.messages[_478.messages.length-1];var _484=new Date().addMinutes(-15);_3da.shortHeartbeat({beforeHeartbeat:tangler.manager.TopicMessageList.onBeforeHeartbeat,callback:tangler.manager.TopicMessageList.heartbeatCallback});if(!tangler.info.Session.getSecurity().isAuthenticated()&& !tangler.info.Page.isEmbed()){new Ext.util.DelayedTask(function(){Ext.get("screenName").focus();},_self).delay(200);}},_viewOlderMessages:function(){Ext.get("viewOldMessageButton").dom.style.display="none";Ext.get("olderMessageLabel").dom.style.display="block";MessageHandler.getOlderMessages(tangler.info.Session.getTopicId(),_3f3,{callback:_self._getOlderMessageReadCallback,errorHandler:_self._getMessagesAndLastReadError,timeout:_3eb});},_getOlderMessageReadCallback:function(_485){var _486=100;var _487=_485.totalAndReadMessageCountReport.totalMessageCount;var _488=_485.totalAndReadMessageCountReport.globalParentId;var _489=parseInt(_3f3+_486);if(_487>_489){Ext.get("olderMessageLabel").dom.style.display="none";Ext.get("viewOldMessageButton").dom.style.display="block";_3f3=_3f3+_486;}else{Ext.get("viewOldMessageButton").dom.style.display="none";Ext.get("olderMessageLabel").dom.style.display="none";}_3e8=_485.lastRead;var _48a=!tangler.info.Session.getSecurity().isAuthenticated();var _48b=_self._buildOlderMessages(_485.messages,{lastRead:_3e8,ignoreLastRead:_48a});var _48c=tangler.cache.CacheManager.getMessageCache();if(_48c[0].globalId!=0&&tangler.util.Element.getEl("message-"+_48c[0].globalId)){tangler.util.Helper.scrollElementTo("message-"+_48c[0].globalId,"messageViewPort");tangler.util.Element.getEl("message-"+_48c[0].globalId).highlight("fffbb4",{easing:"easeIn",duration:5});}else{tangler.util.Helper.scrollElementToEnd("messageViewPort");}if(_485.messages.length>0){var _48d=tangler.info.Session.getMessageLastViewedDate();var _48e=tangler.util.formatter.formatDateTime(_3e8);if(_48e==0||(_48e!=_48d)){_self._sendTopicLastMessageViewed(tangler.info.Session.getTopicId());}}var _48f=_485.messages[_485.messages.length-1];var _490=new Date().addMinutes(-15);_3da.shortHeartbeat({beforeHeartbeat:tangler.manager.TopicMessageList.onBeforeHeartbeat,callback:tangler.manager.TopicMessageList.heartbeatCallback});if(!tangler.info.Session.getSecurity().isAuthenticated()){new Ext.util.DelayedTask(function(){Ext.get("screenName").focus();},_self).delay(200);}},_scrollToMessage:function(_491){if(_491>0){tangler.util.Helper.scrollElementTo("message-"+_491,"messageViewPort");}},_sendTopicLastMessageViewed:function(_492){if(tangler.info.Session.getSecurity().isAuthenticated()){if(_492==0){return;}var _493=tangler.info.Session.getMessageLastViewedDate();var dt=tangler.util.formatter.getDateObject(_493);if(dt==null||dt=="undefined"){return;}DWRTopicHandler.setTopicLastMessageViewed(_492,tangler.util.formatter.getDateObject(_493));}},_getanonymousProfileCallback:function(_495,_496){var _497=tangler.util.Helper.getCnameValue("/images/defaulticons/contact_48.png");var _498=tangler.info.Page.wrapCnameContextUrl("/images/defaulticons/contact_48.png",_497);var _499=tangler.manager.TopicPage.isTopicOwner();var _49a="";var _49b=1;var _49c=1;var _49d=_495.anonymousScreenName;_3f6=tangler.manager.TopicPage.getBannedUserList();if(_499&&(_3f6==null||!_3f6.contains(_495.remoteIp))&&tangler.manager.TopicPage.isUserBannPermission()==true){_49a="<input type='button' id='banButton' value='Ban!' onclick='_self._onClickUserBanButton("+_49c+",\""+_49d+"\",\""+_495.remoteIp+"\","+_49b+")'/>";}_3f8.overwrite("messageAuthorDetails",{authorAvatarUrl:_498,authorScreenName:"<strong>Guest: </strong>"+tangler.util.Helper.escapeHtml(_495.anonymousScreenName),banButton:_49a,authorLocation:"<strong>IP: </strong>"+_495.remoteIp});tangler.util.Element.hideElement("me");tangler.util.Element.hideElement("authorFullName");tangler.util.Element.hideElement("authorActions");},_getUserProfileCallback:function(_49e,_49f){var _4a0=tangler.util.Helper.getCnameValue("/images/defaulticons/contact_48.png");var _4a1=tangler.info.Page.wrapCnameContextUrl("/images/defaulticons/contact_48.png",_4a0);var _4a2="";var _4a3="";var _4a4="";var _4a5="";var gUID=0;var _4a7=_49e.publicProfile.contact?"Chat to ":"Follow ";if(_49e.publicProfile.profileDetail){gUID=_49e.publicProfile.profileDetail.globalId;if(_49e.publicProfile.profileDetail.avatar!=null){_4a1=tangler.util.Avatar.getAvatarUrl(_49e.publicProfile.profileDetail.avatar,{height:48,width:48,avatarType:"user"});}_4a2=_49e.publicProfile.profileDetail.name?_49e.publicProfile.profileDetail.name.fullName:"";_4a3="";_4a4=_49e.publicProfile.profileDetail.occupation?_49e.publicProfile.profileDetail.occupation:"";_4a5=_49e.publicProfile.profileDetail.gender?_49e.publicProfile.profileDetail.gender.description:"";if(_49e.publicProfile.profileDetail.location){if(_49e.publicProfile.profileDetail.location.city!=null&&_49e.publicProfile.profileDetail.location.city.length>0){_4a3+=_49e.publicProfile.profileDetail.location.city;}if(_49e.publicProfile.profileDetail.location.state!=null&&_49e.publicProfile.profileDetail.location.state.length>0){_4a3+=(((_4a3.length>0)?", ":"")+_49e.publicProfile.profileDetail.location.state);}if(_49e.publicProfile.profileDetail.location.country.countryName&&_49e.publicProfile.profileDetail.location.country.countryName!="null"){_4a3+=(((_4a3.length>0)?", ":"")+_49e.publicProfile.profileDetail.location.country.countryName);}}}var _4a8=tangler.util.Helper.escapeHtml(_3d7.getFocusAuthorScreenName());var _4a9=tangler.info.Page.wrapContextUrl("/user/"+_4a8);if(_49e.followed){_4a7="Stop Following";}else{_4a7="Follow";}var _4aa="Add as Friend";var _4ab=tangler.manager.TopicPage.isTopicOwner();var _4ac=0;var _4ad="";_3f6=tangler.manager.TopicPage.getBannedUserList();var _4ae="0";if(_4ab&&(_3f6==null||!_3f6.contains(gUID))&&tangler.manager.TopicPage.isUserBannPermission()==true&&!Ext.get(_49f.parentNode).hasClass("meAuthor")){_4ad="<input type='button' id='banButton' value='Ban!' onclick='_self._onClickUserBanButton("+gUID+",\""+_4a8+"\",\""+_4ae+"\","+_4ac+")'/>";}_3f8.overwrite("messageAuthorDetails",{authorAvatarUrl:_4a1,authorScreenName:_4a8,profileUrl:_4a9,authorFullName:_4a2,authorLocation:_4a3,authorOccupation:_4a4,authorGender:_4a5,interactionUrl:"javascript:void(null);",addFriendLabel:_4aa,interactionType:_4a7,banButton:_4ad});var _4af=tangler.util.Element.getEl("followUserAuthorPopup");if(_4af){if(!tangler.info.Session.getSecurity().isAuthenticated()){Ext.EventManager.addListener(_4af,"click",tangler.manager.ProfileState.onFollowAsAnonymousUser,null,{preventDefault:true});}else{Ext.EventManager.addListener(_4af,"click",tangler.manager.ProfileState.onToggleFollow,{button:_4af,userId:gUID,user:_4a8,followed:_49e.followed},{preventDefault:true});}}var _4b0=tangler.util.Element.getEl("addAsFriendAuthorPopup");if(_4b0){Ext.EventManager.addListener(_4b0,"click",tangler.manager.ProfileState.onAddAsFriend,{button:_4b0,userId:gUID},{preventDefault:true});}tangler.util.Element.hideElement("me");if(!tangler.info.Session.getSecurity().isAuthenticated()){tangler.util.Element.hideElement("interactionLink");tangler.util.Element.hideElement("friend");}if(_3d7.getFocusAuthorId()==tangler.info.Session.getUserId()){tangler.util.Element.hideElement("authorActions");tangler.util.Element.showElement("me");}if(tangler.info.Page.isEmbed()){tangler.util.Element.getEl("profileLink").dom.href="javascript:void(0);";tangler.util.Element.getEl("profileLink").on("click",function(){window.open(_4a9);},this,{preventDefault:true});}if(!_49e.publicProfile.contact){}else{tangler.util.Element.hideElement("friendOpt");}if(_4a2==""){tangler.util.Element.hideElement("authorFullName");}if(_4a3==""){tangler.util.Element.hideElement("authorLocation");}if(_4a4=""){tangler.util.Element.hideElement("authorOccupation");}if(_4a5==""){tangler.util.Element.hideElement("authorGender");}},_onClickUserBanButton:function(_4b1,_4b2,_4b3,_4b4){if(confirm("Are you sure that you want to ban this user?")){var _4b5=tangler.info.Session.getTopicId();var _4b6="USER_ID|"+_4b1+"|SCREEN_NAME|"+_4b2+"|ANONYMOUS_USER|"+_4b4+"|REMOTE_IP_ADDRESS|"+_4b3+"";var _4b7=-1;MessageHandler.createMessage(_4b5,_4b6,_4b7,{callback:function(msg){_self._updateCreatedMessage(msg);},errorHandler:_self._createMessageFailed});if(_3f6==null){if(_4b4==0){_3f6[0]=_4b1;}else{_3f6[0]=_4b3;}}else{var _4b9=_3f6.length;if(_4b4==0){_3f6[_4b9]=_4b1;}else{_3f6[_4b9]=_4b3;}}}},_createMessageCallback:function(_4ba){if(_3e7!=null&&_3e7.isVisible()){_3e7.hide();}if(_4ba==null){_3de.setInputContent(messagePending);_3de.focusInput();return;}_3e8=_4ba.detail.lastModified;_self._buildMessage(_4ba,{ignoreLastRead:true});_self._scrollToMessage(_4ba.detail.globalId);tangler.info.Session.setMessageLastViewedDate(tangler.util.formatter.formatDateTime(_4ba.detail.lastModified));if(tangler.info.Session.getSecurity().isAuthenticated()&&!_3d8.getTopicWatched()){_3d8.setTopicWatched(true);}if(tangler.util.Helper.canScroll("messageViewPort","messages")){tangler.util.Helper.scrollElementToEnd("messageViewPort");}_self._sendTopicLastMessageViewed(tangler.info.Session.getTopicId());if(Ext.isSafari){}_3ee=true;},_createMessageFailed:function(_4bb){if(_3e7!=null&&_3e7.isVisible()){_3e7.hide();}if(_4bb=="Banned User"){alert("You are banned from this topic!");var _4bc=tangler.util.Element.getEl("messageEditorOverlay");var _4bd=tangler.util.Element.createNode("div",{attributes:[["class","ieFill"]]});var _4be="You have been banned from this conversation. The reason being that your contributions to this topic have resulted in the topic creator electing to ban you.";var _4bf=tangler.util.Element.createNode("div",{attributes:[["class","input"]]});var msg=tangler.util.Element.createNode("div",{attributes:[["class","message"]]});var br=tangler.util.Element.createNode("br");var h4=tangler.util.Element.createNode("h3",{attributes:[[]],children:[document.createTextNode(_4be)]});var _4c3=tangler.util.Element.createNode("div",{attributes:[["id","tnc_div"],["class","tnc_div"]],children:[_4bd,msg,_4bf,br,h4]});tangler.util.Element.removeChildNodes("messageEditorOverlay");_4bc.appendChild(_4c3);_4bc.show();}else{alert("We were unable to send your message, please try again");_3de.setInputContent(messagePending);_3de.focusInput();}},_updateCreatedMessage:function(_4c4,_4c5){if(_4c4.detail.parentMessageId!=null&&_4c4.detail.parentMessageId<0){alert("You have successfully banned this user from this topic.");return;}var _4c6=tangler.util.Element.getEl("message-"+_4c5);if(_3e7!=null&&_3e7.isVisible()){_3e7.hide();}if(_4c4.permissions.quotable){var _4c7=tangler.util.StringUtil.getQuoteMessageOrMessageBody(_4c4.detail.body,false);var _4c8=tangler.util.StringUtil.getTextAndRemoveHtmlTags(_4c7);if(_4c8==null||_4c8==""){_4c4.permissions.quotable=false;}}var _4c9=new tangler.domain.MessageElement(_4c4.detail,_4c4.permissions,_4c4.auditHistory);var _4ca={};_3f4=0;_3f5="";_4ca=_self._setCreateMessageEventArguments(_4ca,_4c4);_4c9.updateElementOnCallback(_4c5,_4ca,_4c4);delete _4c9;},_showTopicHeader:function(_4cb,_4cc){_3d9.setTopicLifecycle(_4cb);var _4cd=_4cb.detail.topicDetail.name;var _4ce=_4cd==null?"General Conversation":_4cd;_4ce=tangler.util.Helper.escapeHtml(_4ce);var _4cf="http://"+window.location.host+tangler.info.Page.wrapContextUrl("/topics/viewTopic.action?tId="+tangler.info.Session.getTopicId());tangler.util.Element.getEl("topicName").update(_4ce);var _4d0=tangler.util.Element.getEl("userFollowOption");var _4d1=_4d0==null?30:_4d0.getWidth()+80;if(tangler.util.Helper.metricEllipsis("topicName",{offset:_4d1})){tangler.util.Element.getEl("topicName").dom.title=_4ce;}},_autoPostDaemon:function(){if(!_3ee){return;}_3ee=false;_3de.setInputContent(_self._makeRandomStr());_self.submitMessage();},_makeRandomStr:function(){var msg="";var _4d3=_3ec.length;var _4d4=Math.floor(Math.random()*10)+1;for(i=0;i<_4d4;i++){for(j=0;j<8;j++){var _4d5=Math.floor(Math.random()*_4d3);msg+=_3ec.charAt(_4d5);}msg+=" ";}msg="<strong>"+(_3ed++)+"</strong> "+msg;return msg;}});return new _3f9();}();
tangler.widget.SocialNWSites={twitter:"twitter",facebook:"facebook",digg:"digg"};tangler.widget.TopicWidgets=function(){var _29f="grabLinkTxt";var _2a0="grabLinkBtn";var _2a1="grabEmbedTxt";var _2a2="grabEmbedBtn";var _2a3="twittBtn";var _2a4="facebookBtn";var _2a5="diggBtn";var _2a6=null;var _2a7;var _2a8=0;var _2a9="";var _2aa="http://tlive.me/";var _2ab=function(){this.topicAuthorId=0;_2ab.superclass.constructor.call(this);};Ext.extend(_2ab,Ext.util.Observable,{init:function(_2ac){_2a8=tangler.util.Options.getOptionalArgument("topicId",_2ac,0);_2a9=tangler.util.Options.getOptionalArgument("topicName",_2ac,"");_2aa=_2aa+_2a8;this._topicId=_2a8;this._topicName=_2a9;this._shortUrl=_2aa;this.setTopicLink();this.setEmbedText();Ext.EventManager.addListener(Ext.get(_2a3),"click",this.twittIt,this,{preventDefault:true});Ext.EventManager.addListener(Ext.get(_2a4),"click",this.faceBookIt,this,{preventDefault:true});var _2ad=tangler.info.Page.wrapFullContextUrl("/flash/ZeroClipboard.swf");ZeroClipboard.setMoviePath(_2ad);this.clipBoard=new ZeroClipboard.Client();this.clipBoard.setHandCursor(true);_widgetRef=this;Ext.EventManager.addListener(Ext.get(_2a0),"mouseover",function(evt,t,o){this.clipBoard.setText(document.getElementById("grabLinkTxt").value);if(this.clipBoard.div){this.clipBoard.receiveEvent("mouseout",null);this.clipBoard.reposition(evt.target);}else{this.clipBoard.glue(evt.target);}this.clipBoard.receiveEvent("mouseover",null);},_widgetRef,{preventDefault:true});Ext.EventManager.addListener(Ext.get(_2a2),"mouseover",function(evt,t,o){this.clipBoard.setText(document.getElementById("grabEmbedTxt").value);if(this.clipBoard.div){this.clipBoard.receiveEvent("mouseout",null);this.clipBoard.reposition(evt.target);}else{this.clipBoard.glue(evt.target);}this.clipBoard.receiveEvent("mouseover",null);},_widgetRef,{preventDefault:true});},grabLink:function(){},embedTopic:function(){},twittIt:function(){this._postOnSWNSitesResponse(tangler.widget.SocialNWSites.twitter);DWRTopicHandler.addPostOnSNWService(tangler.widget.SocialNWSites.twitter,this._topicId,{callback:function(data){},errorHandler:this._postOnSWNSitesResponseError});},faceBookIt:function(){this._postOnSWNSitesResponse(tangler.widget.SocialNWSites.facebook);DWRTopicHandler.addPostOnSNWService(tangler.widget.SocialNWSites.facebook,this._topicId,{callback:function(data){},errorHandler:this._postOnSWNSitesResponseError,async:false});},diggIt:function(){this._postOnSWNSitesResponse(tangler.widget.SocialNWSites.digg);DWRTopicHandler.addPostOnSNWService(tangler.widget.SocialNWSites.digg,this._topicId,{callback:function(data){},errorHandler:this._postOnSWNSitesResponseError});},shareIt:function(){if(_2a7==null){_2a7=new tangler.widget.DialogWrapper("shareTopic-dlg",{height:160,resizable:false,draggable:false,acceptLabel:"Invite",acceptFunction:function(){_2a7.hide();},declineLabel:"Cancel",declineFunction:function(){_2a7.hide();}});_2a7.addListener("beforeHide",function(_2b7){alert("Emails sent!");});}if(_2a7.isVisible()){return;}_2a7.showDialog();},setAction:function(_2b8){alert(_2b8);},setTopicLink:function(){if(this._topicId!=0){Ext.get(_29f).dom.value=this._shortUrl;}},setEmbedText:function(){if(this._topicId!=0){var _2b9=tangler.info.Page.wrapFullContextUrl("/widget/embedtopic.js?id="+this._topicId);if(tangler.info.Page.isDebug()){_2b9+="&cUrl="+tangler.info.Page.wrapFullContextUrl("");}var _2ba="<p style=\"width:100%;height:714px;\" id=\"tangler-embed-topic-"+this._topicId+"\"></p><script src=\""+_2b9+"\"></script>";Ext.get(_2a1).dom.value=_2ba;}},_postOnSWNSitesResponse:function(data){var _2bc="http://tlive.me/"+tangler.widget.TopicWidgets._topicId;if(data){var _2bd="";switch(data){case tangler.widget.SocialNWSites.twitter:var _2be=tangler.widget.TopicWidgets._topicName;_2be=escape(_2be);var _2bf="Now chatting in "+_2be+". Join me! "+tangler.widget.TopicWidgets._shortUrl+" %23TanglerLive ";_2bd="http://twitter.com/home/?status="+_2bf;break;case tangler.widget.SocialNWSites.facebook:_2bd="http://www.facebook.com/sharer.php?u="+_2bc;break;case tangler.widget.SocialNWSites.digg:_2bd="http://digg.com/submit?phase=2&url="+_2bc;break;}var win=null;if(data==tangler.widget.SocialNWSites.facebook){win=window.open(_2bd,"newwindow","width=700,height=307,resizable=0");}else{win=window.open(_2bd);}if(!win){alert("There was an error when tanglerlive tried to post on "+data+"!\nPlease check if you have blocked pop-ups.");}}},_postOnSWNSitesResponseError:function(_2c1){alert("Some errors occured during the operation: "+_2c1);}});return new _2ab();}();tangler.manager.TopicPage=function(){var _2c2=tangler.util.Options;var _2c3=tangler.manager.TopicMessageList;var _2c4=tangler.util.Element;var _2c5=tangler.manager.Comms;var _2c6=tangler.info.Page;var _2c7=tangler.util.Helper;var _2c8=tangler.info.Session;var _2c9=tangler.widget.TopicWidgets;var _2ca=0;var _2cb=0;var _2cc=false;var _2cd;var _2ce=false;var _2cf=null;var _2d0=0;var _me=this;var _2d2=null;var _2d3=false;var _2d4;function renderDiscuss(_2d5){_2c3.init(_2d5);var _2d6=_2cb;if(_2d6!=0){_2c3.getMessagesAndScroll(_2d6,_2d0);}}function onDiscussClicked(){}return {initTopicLayout:function(_2d7){var _2d8=_2c4.getEl(_2c2.getOptionalArgument("messageOverlay",_2d7,"messageEditorOverlay"));if(_2c8.getSecurity().isAuthenticated()&&_2d8){_2d8.hide();}else{if(_2d8){_2d8.show();}}var _2d9=tangler.info.Page.isEmbed();_2c6.setView(_2d9?tangler.info.ViewType.TopicEmbedDiscuss:tangler.info.ViewType.TopicDiscuss);var _2da=_2c2.getOptionalArgument("topicId",_2d7,0);var _2db=_2c2.getOptionalArgument("groupId",_2d7,0);_2d0=_2c2.getOptionalArgument("messageToShow",_2d7,0);_2cb=_2da;_2ca=_2db;tangler.info.Session.setGroupId(_2db);tangler.info.Session.setTopicId(_2da);dwr.engine.beginBatch();DWRGroupHandler.registerGroup(tangler.info.Session.getGroupId());dwr.engine.endBatch();_2cd=_2c2.getOptionalArgument("messagesDiv",_2d7,"messages");var _2dc=_2c2.getOptionalArgument("topicCreatorId",_2d7,0);_2cc=(_2dc==tangler.info.Session.getUserId());_2d3=_2c2.getOptionalArgument("bannUserPermission",_2d7,0);_2d4=_2c2.getOptionalArgument("bannedUserArray",_2d7,0);Ext.QuickTips.init();renderDiscuss(_2d7);if(!_2d9){_2c9.init(_2d7);}if(!_2c8.getSecurity().isAuthenticated()){if(Ext.isSafari){var _2dd=_2c4.getEl("messageSendButton");_2dd.on("focus",function(){document.getElementById("joinAnonymously").focus();},null);}var _2de=_2c4.getEl("joinAnonymously");_2de.on("click",this.validateAnonymousJoin,this);_2de.on("mouseover",function(){this._inTcCc=true;this._TcnCcFocused();},this);_2de.on("mouseout",function(){this._inTcCc=false;this._TcnCcUnFocused();},this);var _2df=_2c4.getEl("tnc_div");_2df.on("mouseover",function(){this._inTcCc=true;},this);_2df.on("mouseout",function(){this._inTcCc=false;this._TcnCcUnFocused();},this);}},isTopicOwner:function(){return _2cc;},isUserBannPermission:function(){return _2d3;},getBannedUserList:function(){return _2d4;},shutdown:function(_2e0){DWRGroupHandler.deregisterGroup(tangler.info.Session.getTopicId());},removeTopic:function(){if(confirm("Are you sure that you want to delete this topic?")){DWRTopicHandler.removeTopic(tangler.info.Session.getTopicId(),{callback:this._removeTopicCallback,errorHandler:this._removeTopicErrCallback});}},_removeTopicCallback:function(){alert("The topic was succesfully deleted.\nHowever, it may take a while to remove from cache!");window.location.href="/home";},_removeTopicErrCallback:function(){alert("We were not able to delete that topic.");},initDiscussionPage:function(_2e1){},validateAnonymousJoin:function(){if($("screenName").value.trim()==""){this._anonymousJoinCallback("SN:invalid");return;}DWRTopicHandler.joinAnonymously($("screenName").value,$("captchaInput").value,tangler.info.Session.getTopicId(),{callback:this._anonymousJoinCallback,errorHandler:this._anonymousJoinCallbackError});},_anonymousJoinCallback:function(_2e2){_2c4.getEl("captchaError").hide();_2c4.getEl("screenNameError").hide();if(_2e2==""){if(Ext.isSafari){var _2e3=_2c4.getEl("messageSendButton");_2e3.on("focus",null,null);}_2c4.getEl("tnc_div").hide();_2c4.getEl("messageEditorOverlay").hide();_2c8.getSecurity().joinAnonymously(true);_2c8.setUser($("screenName").value);_2c3.getEditor().focusInput();return;}else{if(_2e2==("C:"+$("captchaInput").value)){_2c4.getEl("captchaError").show();tangler.manager.TopicPage.reloadCaptcha();}else{if(_2e2==("SN:"+$("screenName").value)){_2c4.getEl("screenNameError").dom.title="The Screen Name already exists. Please try another.";_2c4.getEl("screenNameError").dom.innerHTML="Name taken";_2c4.getEl("screenNameError").show();tangler.manager.TopicPage.reloadCaptcha();}else{if(_2e2=="SN:invalid"){_2c4.getEl("screenNameError").dom.title="Invalid Screen Name.";_2c4.getEl("screenNameError").dom.innerHTML="Invalid screen name";_2c4.getEl("screenNameError").show();tangler.manager.TopicPage.reloadCaptcha();}}}}_2c4.getEl("captchaInput").dom.value="";},_anonymousJoinCallbackError:function(_2e4){alert("Error: "+_2e4);},reloadCaptcha:function(){var _2e5=_2c4.getEl("captchaImage").dom.src;var _2e6=_2e5;var rand=Math.floor(Math.random()*10);if(_2e5.endsWith("/tl")){_2e6+="/"+rand;}else{_2e6+=rand;}Ext.get("captchaImage").dom.src=_2e6;},_TcnCcFocused:function(){Ext.get("tnc_div").show();},_TcnCcUnFocused:function(){if(this._TcCcDelayedTask==null){this._TcCcDelayedTask=new Ext.util.DelayedTask();}this._TcCcDelayedTask.delay(1000,function(){if(this._inTcCc==true){return;}Ext.get("tnc_div").fadeOut({endOpacity:0,easing:"easeOut",duration:0.5,remove:false,useDisplay:false,callback:function(){Ext.get("tnc_div").hide();}});},this);},sortAlg:function(a,b){var _2ea=a.screenName.toLowerCase();var _2eb=b.screenName.toLowerCase();if(_2ea<_2eb){return -1;}else{if(_2ea>_2eb){return 1;}else{return 0;}}},presenceEvent:function(_2ec,_2ed){var _2ee=Ext.get("participants");if(_2ec.length==0){return;}var _2ef=_2ec[0];if(_2ef.anonymous&&(_2ef.screenName==null||_2ef.screenName=="")){return;}var pid="id-"+_2ef.screenName+"-"+_2ef.globalId;var _2f1=_2ee.child("#"+pid);var _2f2=Ext.get("chatMembersCount");var cnt=_2f2.dom.innerHTML*1;var _2f4=_2ee.child("#id-anon > #id-anoncnt");if(_2ef.screenName=="anonymousUser"){if(_2f4!=null){var _2f5=_2f4.dom.innerHTML*1;if(_2ed){_2f5--;}else{_2f5++;}_2f4.dom.innerHTML=_2f5;}return;}if(_2ed){if(_2f1!=null){_2f1.remove();cnt=cnt-1;_2f2.dom.innerHTML=cnt;}return;}if(_2f1!=null){return;}var _2f6=_2ee.createChild({"tag":"li","id":pid});if(_2ef.anonymous){_2f6.dom.innerHTML="Guest: "+_2ef.screenName;}else{_2f6.dom.innerHTML="<a target='_blank' href='/user/"+_2ef.globalId+"'>"+_2ef.screenName+"</a>";}cnt=cnt+1;_2f2.dom.innerHTML=cnt;},toggleDaemon:function(_2f7){var val=Ext.get("jsDaemonButton").dom.value;if(_2d2==null){_2d2={run:_2c3._autoPostDaemon,interval:_2f7};}if(val=="Stop Test Task"){Ext.TaskMgr.stop(_2d2);Ext.get("jsDaemonButton").dom.value="Run Test Task";}else{Ext.TaskMgr.start(_2d2);Ext.get("jsDaemonButton").dom.value="Stop Test Task";}}};}();
tangler.manager.ProfileState=function(){var _24d=null;var _24e=function(){this.isFollowed=false;this.isFollower=false;this.isContact=false;this.profileId=0;this.profileOwnerScreenName=null;this.viewerId=0;this.viewType=null;_24e.superclass.constructor.call(this);_pState=this;};Ext.extend(_24e,Ext.util.Observable,{setFollwer:function(_24f){this.isFollower=_24f;},getFollower:function(){return this.isFollower;},setFollwed:function(_250){this.isFollowed=_250;},getFollowed:function(){return this.isFollowed;},setProfileId:function(id){this.profileId=id;},getProfileId:function(){return this.profileId;},setViewerId:function(id){this.viewerId=id;},getViewerId:function(){return this.viewerId;},setContact:function(_253){this.isContact=_253;},isContact:function(){return this.isContact;},setProfileOwnerScreenName:function(_254){this.profileOwnerScreenName=_254;},getProfileOwnerScreenName:function(){return this.profileOwnerScreenName;},onAddAsFriend:function(){var _255=(this.userId!="undefined"&&this.userId!=null)?this.userId:_pState.profileId;var args={button:this.button};DWRUserHandler.addAsFriend(_255,"",{callback:function(data){_pState._addedFriendCallbackSuccess(data,args);},errorHandler:_pState._addedFriendCallbackFailure});},onToggleFollow:function(){var _258=(this.userId!="undefined"&&this.userId!=null)?this.userId:0;var _259=(this.followed!="undefined"&&this.followed!=null)?this.followed:_pState.isFollowed;var args=null;if(_258==0){_258=_pState.profileId;args={button:this.button};}else{args=this;}args.followUserId=_258;DWRUserHandler.toggleFollow(_258,!_259,{callback:function(data){_pState._toggleCallbackSuccess(data,args);},errorHandler:_pState._toggleCallbackFailure});},_toggleCallbackSuccess:function(_25c,args){if(!_25c){Ext.MessageBox.show({title:"Message Warning",msg:"There was some problem while executing your request. <br />Please try after sometimes.",buttons:Ext.MessageBox.OK});}var _25e="";if(args.userId!=null){var _25f=!args.followed?"Stop Following ":"Follow ";_25e=_25f;args.followed=!args.followed;}else{var _25f=!_pState.isFollowed?"Stop Following ":"Follow ";_pState.setFollwed(!_pState.isFollowed);_25e=_25f;}tangler.util.Element.getEl(args.button).update(_25e);Ext.EventManager.removeListener(args.button,"click",tangler.manager.ProfileState.onToggleFollow);Ext.EventManager.addListener(args.button,"click",tangler.manager.ProfileState.onToggleFollow,args,{preventDefault:true});if(tangler.info.Page.getView()==tangler.info.ViewType.TopicDiscuss&&args.userId!=null&&args.userId==_pState.profileId){if(tangler.util.Element.getEl("followTopicOwner")){tangler.util.Element.getEl("followTopicOwner").update(_25e);}}else{if(tangler.info.Page.getView()==tangler.info.ViewType.Profile&&args.userId!=null&&args.userId==_pState.profileId){}}},_toggleCallbackFailure:function(){},_addedFriendCallbackSuccess:function(data,args){if(data==true){Ext.get(args.button).dom.style.display="none";}},_addedFriendCallbackFailure:function(){},onFollowAsAnonymousUser:function(){if(_24d==null){_24d=new tangler.widget.DialogWrapper("join-dlg",{minHeight:80,width:230,height:80,draggable:false,resizable:false,acceptLabel:"Ok",defaultFocus:"Ok",acceptFunction:function(){_24d.hide();}});}if(_24d.isVisible()){return;}_24d.showDialog();},init:function(_262){this.isFollower=tangler.util.Options.getOptionalArgument("isFollower",_262,false);this.isFollowed=tangler.util.Options.getOptionalArgument("isFollowed",_262,false);this.profileId=tangler.util.Options.getOptionalArgument("profileId",_262,0);this.profileOwnerScreenName=tangler.util.Options.getOptionalArgument("profileName",_262,null);this.viewerId=tangler.util.Options.getOptionalArgument("viewerId",_262,0);this.viewType=tangler.util.Options.getOptionalArgument("viewType",_262,null);if(!tangler.info.Page.isEmbed()&&!tangler.info.Session.getSecurity().isAuthenticated()){var view=tangler.info.Page.getView();var _264=null;switch(view){case tangler.info.ViewType.Profile:_264=tangler.util.Element.getEl("followUserButton");if(_264!=null){_264.on("click",tangler.manager.ProfileState.onFollowAsAnonymousUser,this);}break;case tangler.info.ViewType.TopicDiscuss:_264=tangler.util.Element.getEl("followTopicOwner");if(_264!=null){_264.on("click",tangler.manager.ProfileState.onFollowAsAnonymousUser,this);}break;}}}});return new _24e();}();

var isSafari = false;

if (typeof navigator.vendor != "undefined" && navigator.vendor.indexOf("Apple Computer, Inc.") != -1)
{
	isSafari = true;
}

var widgPlugins = {};

//TW-1781
var widgInstance = null;

/* Setup the onload events to convert textareas */
Ext.EventManager.onDocumentReady(widgInit);

/* Find all the textareas that need to be converted */
function widgInit()
{
	/* Detects if designMode is available, and also if browser is IE or Mozilla (excludes earlier versions of Safari) */
	if (typeof(document.designMode) == "string" && (document.all || document.designMode == "off"))
	{
		var textareas = document.getElementsByTagName("textarea");
		
		for (var i = 0; i < textareas.length; i++)
		{
			var textarea = textareas[i];
			
			if (Ext.get(textarea).hasClass("widgEditor"))
			{
				if (textarea.id == null || textarea.id == "")
				{
					textarea.id = textarea.name;
				}

				textarea.style.visibility = "hidden";
				
				setTimeout("new widgEditor('" + textarea.id + "')", 500 * (i));
			}
		}
	}
	else
	{
		return false;
	}
	
	return true;
};




/* Class for each individual widgEditor */
function widgEditor(replacedTextareaID, options)
{
	var self = this;
	
	if (typeof options == "undefined")
	{
		options = {};
	}
	
	if (typeof options.toolbarButtons == "undefined")
	{
		options.toolbarButtons = widgConfig.toolbarButtons
	}
	
	if (typeof options.toolbarSelects == "undefined")
	{
		options.toolbarSelects = widgConfig.toolbarSelects
	}

	this.id = replacedTextareaID;
	this.toolbarButtons = options.toolbarButtons;
	this.toolbarSelects = options.toolbarSelects;
	this.textarea = document.getElementById(replacedTextareaID);
	
	if (typeof document.all == "undefined" && this.textarea.value.match(/^\s*$/))
	{
		this.textarea.value = "<br />";
	}
	
	this.ready = false;
	this.cancelToolbarCheck = false;
	this.dialogLock = false;
	this.pasteCache = "";
	this.chatMode = false;
	this.submitAction = function()
	{
		var self = this;
		var theForm = this.container.parentNode;
		var oldOnsubmit = null;
		
		/* Find the parent form element */
		while (theForm.parentNode != null && theForm.nodeName.toLowerCase() != "form")
		{
			theForm = theForm.parentNode;
		}
	
		if (theForm.parentNode != null)
		{
			theForm.submit();
		}
		
		return false;
	};
	
	/* Create DOM objects for editor */
	this.container = document.createElement("div");
	this.container.id = this.id + "WidgContainer";
	this.container.className = "widgContainer";
	this.container.style.visibility = "hidden";
	
		this.input = document.createElement("input");
		this.input.type = "hidden";
		this.input.id = this.id;
		this.input.name = this.textarea.name;
		this.input.value = this.textarea.value;
		this.input.editor = this;
		this.container.appendChild(this.input);

		this.toolbar = new widgToolbar(this, this.toolbarButtons, this.toolbarSelects);
		
		this.container.appendChild(this.toolbar.theList);

	this.textarea.parentNode.replaceChild(this.container, this.textarea);

	this.textarea.id += "WidgTextarea";
	this.textarea.name += "WidgTextarea";
	this.isQuote = false;

	this.createIframe();	
	
	/* Attach onsubmit to parent form */
	this.modifyFormSubmit();
	
	//TW-1781
	widgInstance = this;
	
	return this;
};




widgEditor.prototype.createIframe = function()
{
	if (typeof this.iframe != "undefined")
	{
		this.iframe.parentNode.removeChild(this.iframe);
		delete this.iframe;

		var self = this;
		
		/* timeout required for Safari, which takes a while to remove original iframe */
		setTimeout(function()
			{
				self.createIframe();
			},
			1
		);
		
		return false;
	}
	
	this.iframe = document.createElement("iframe");
	this.iframe.id = this.input.id + "WidgIframe";
	this.iframe.className = "widgIframe";
	this.iframe.setAttribute("frameborder", "0");
	this.iframe.setAttribute("frameBorder", "0");
	this.container.appendChild(this.iframe);

	this.iframeWindow = this.iframe.contentWindow;
	this.iframeDocument = this.iframeWindow.document;
	
	/* Fill editor with old textarea content */
	this.writeDocument(this.input.value);
	
	/* Make editor editable */
	this.initEdit();
};




/* Clean pasted content */
widgEditor.prototype.cleanPaste = function()
{
	if (widgConfig.autoClean || confirm("Do you wish to clean the HTML source of the content you just pasted?"))
	{
		markSelectionBoundaries(this.iframeWindow);
		
		this.paragraphise();
		//getting quote div from editor
		var quoteDisableText = this.iframeDocument.getElementById("quoteDisableText");
		
		this.input.value = cleanSource(this.iframeDocument.body.innerHTML, true);
		
		/* Strip out unaccepted attributes */
		this.input.value = this.input.value.replace(/<[^>]*>/g, function(match)
			{
				match = match.replace(/ ([^=]+)="[^"]*"/g, function(match2, attributeName)
					{
						if (attributeName == "alt" || attributeName == "href" || attributeName == "src" || attributeName == "title" || attributeName == "id" || attributeName == "class")
						{
							return match2;
						}

						return "";
					});

				return match;
			}
		);
		
		var tempNode = document.createElement("div");
		tempNode.innerHTML = this.input.value

		acceptableChildren(tempNode);

		this.input.value = tempNode.innerHTML;

		this.refreshDisplay(true);
		
		//for quote message div appending to the editor
		if(!tangler.util.StringUtil.isEmpty(quoteDisableText) )
		{
			this.iframeDocument.getElementsByTagName("body")[0].removeChild(this.iframeDocument.body.firstChild);
			this.iframeDocument.body.insertBefore( quoteDisableText, this.iframeDocument.body.firstChild );
			
		}
	}
	
	return true;
};




/* Check for pasted content */
widgEditor.prototype.detectPaste = function(theEvent)
{
	if (theEvent.ctrlKey && theEvent.getKey() == 86)
	{
		var self = this;
		
		this.pasteCache = this.iframeDocument.getElementsByTagName("body")[0].innerHTML;

		/* Because Mozilla can't access the clipboard directly, must rely on timeout to check pasted differences in main content */
		setTimeout(function(){self.cleanPaste(); return true;}, 100);
	}

	return true;
};




/* Check for shortcut keys */
widgEditor.prototype.detectShortcuts = function(event)
{
	if (event.ctrlKey)
	{
		switch(event.getKey())
		{
			case 13:

				this.handleControlKeys(event);
				
				break;
			
			/* Ctrl-b */
			case 66:
			
				var listItems = this.toolbar.theList.childNodes;
				var button = listItems[0];
				
				while (button != null && !Ext.get(button).hasClass("widgButtonBold"))
				{
					button = button.nextSibling;
				}
				
				var input = button.getElementsByTagName("input")[0];
				
				onclickBold.call(input);

				event.preventDefault();
				this.cancelToolbarCheck = true;
				return false;
			
				break;

			/* Ctrl-i */
			case 73:
			
				var listItems = this.toolbar.theList.childNodes;
				var button = listItems[0];
				
				while (button != null && !Ext.get(button).hasClass("widgButtonItalic"))
				{
					button = button.nextSibling;
				}
				
				var input = button.getElementsByTagName("input")[0];
				
				onclickItalic.call(input);
				
				event.preventDefault();
				this.cancelToolbarCheck = true;
				return false;
			
				break;

			/* Ctrl-u */
			case 85:
			
				var listItems = this.toolbar.theList.childNodes;
				var button = listItems[0];
				
				while (button != null && !Ext.get(button).hasClass("widgButtonUnderline"))
				{
					button = button.nextSibling;
				}
				
				var input = button.getElementsByTagName("input")[0];
				
				onclickUnderline.call(input);
				
				event.preventDefault();
				this.cancelToolbarCheck = true;
				return false;
			
				break;
		}
		
		this.cancelToolbarCheck = true;
	}

	return true;
};





/* Check keystrokes for control keys i.e. carriage return, backspace; and handle appropriately */
widgEditor.prototype.handleControlKeys = function(event)
{
	/* "return" key pressed */
	if (event.getKey() == 13)
	{
		/* Prevent IE from receiving keypresses from dialogs */
		if (this.dialogLock == true)
		{
			event.preventDefault();

			return false;
		}
		
		if ((!widgConfig.shiftSubmit && event.shiftKey == false) || (!widgConfig.shiftSubmit && event.ctrlKey == true) || (widgConfig.shiftSubmit && event.shiftKey == true) || (this.chatMode && event.ctrlKey != true && event.shiftKey != true))
		{
			this.submit();

			event.preventDefault();
		}
		else if (markSelectionBoundaries(this.iframeWindow))
		{
			this.paragraphise(false);

			var selectionStart = this.iframeDocument.getElementById("selectionStart");
			var selectionEnd = this.iframeDocument.getElementById("selectionEnd");

			deleteSelection(this.iframeWindow);

			/* Insert a <br> */
			if (event.shiftKey == true || event.ctrlKey == true)
			{
				var newBr = this.iframeDocument.createElement("br");

				selectionStart.parentNode.insertBefore(newBr, selectionStart);
			}
			/* Create new block element */
			else
			{
				var blockParent = selectionStart.parentNode;

				while (!blockParent.nodeName.isBlockName())
				{
					blockParent = blockParent.parentNode;
				}
				
				/* If the cursor has been newly inserted right at the start of the document i.e. just inside the body tag, move the cursor into the first block element */
				if (blockParent.nodeName.toLowerCase() == "body")
				{
					var firstBlock = blockParent.firstChild;
					
					while (firstBlock != null)
					{
						if (firstBlock.nodeType == 1 && firstBlock.nodeName.isBlockName())
						{
							blockParent = firstBlock;
							blockParent.insertBefore(selectionEnd, blockParent.firstChild);
							blockParent.insertBefore(selectionStart, blockParent.firstChild);
							
							break;
						}
						
						firstBlock = getNextElement(firstBlock);
					}

					if (firstBlock == null)
					{
						blockParent = this.iframeDocument.createElement("p");
						
						while (this.iframeDocument.body.firstChild != null)
						{
							blockParent.appendChild(this.iframeDocument.body.firstChild);
						}
						
						blockParent.insertBefore(selectionEnd, blockParent.firstChild);
						blockParent.insertBefore(selectionStart, blockParent.firstChild);
						
						this.iframeDocument.body.appendChild(blockParent);
					}
				}

				/* Last list item of a list is empty, create new paragraph */
				if (blockParent.nodeName.toLowerCase() == "li" && blockParent.innerHTML.match(/^(\s|&nbsp;|\xA0|<var[^>]*>|<\/var>|<br[^>]*>)*$/i) != null)
				{
					var newP = this.iframeDocument.createElement("p");
					newP.innerHTML = blockParent.innerHTML;
					blockParent.parentNode.parentNode.insertBefore(newP, blockParent.parentNode.nextSibling);
					
					blockParent.parentNode.removeChild(blockParent);
				}
				else
				{
					var blockCopy = blockParent.cloneNode(true);
					var blockCopySelectionStart = getNextElement(blockCopy);
	
					/* Find the cloned selectionStart */
					while (blockCopySelectionStart.id != "selectionStart")
					{
						blockCopySelectionStart = getNextElement(blockCopySelectionStart);
					}
	
					var nextElement = getNextElement(blockCopy);
	
					/* Remove elements from clone prior to selection point */
					while (nextElement.id != "selectionStart")
					{
						if (!isDescendantNode(blockCopySelectionStart, nextElement))
						{
							var currElement = nextElement;
							nextElement = getNextHigherElement(nextElement);
							currElement.parentNode.removeChild(currElement);
						}
						else
						{
							nextElement = getNextElement(nextElement);
						}
					}

					if (isEmptyElement(blockCopy, true))
					{
						blockCopy.innerHTML += "&nbsp;";
					}
					
					var anchors = blockCopy.getElementsByTagName("a")
					
					for (var i = anchors.length - 1; i >= 0; i--)
					{
						replaceNodeWithChildren(anchors[i]);
					}
	
					if (blockParent.nodeName.toLowerCase() == "li")
					{
						blockParent.parentNode.insertBefore(blockCopy, blockParent.nextSibling);
					}
					else
					{
						var newP = this.iframeDocument.createElement("p");
	
						newP.appendChild(blockCopy);
						replaceNodeWithChildren(blockCopy);
						blockParent.parentNode.insertBefore(newP, blockParent.nextSibling);
						
						newP.innerHTML += "&nbsp;"
					}
	
					var nextElement = selectionStart;
	
					/* Remove elements from original block after selection point */
					while (isDescendantNode(nextElement, blockParent))
					{
						var currElement = nextElement;
						nextElement = getNextHigherElement(nextElement);
						currElement.parentNode.removeChild(currElement);
					}

					if (isEmptyElement(blockParent))
					{
						blockParent.innerHTML += "&nbsp;";
					}
				}
			}

			/* Scroll so new element is in view */
			this.iframeWindow.scrollTo(0, getPosition(newBr || newP || blockCopy)[1] - this.iframe.clientHeight + 30);
			
			selectSelectionBoundaries(this.iframeWindow);
			deleteSelectionBoundaries(this.iframeWindow);

			event.preventDefault();
		}
		else
		{
			return false;
		}
	}
	
	return true;
};




/* Turn on document editing */
widgEditor.prototype.initEdit = function()
{
	var self = this;
	
	try
	{
		this.iframeDocument.designMode = "on";
	}
	catch (e)
	{
		/* setTimeout needed to counteract Mozilla bug whereby you can't immediately change designMode on newly created iframes */
		setTimeout(function(){self.initEdit()}, 250);
			
		return false;
	}

	this.container.style.visibility = "visible";
	this.textarea.style.visibility = "visible";
	
	/* Capture events on the iframe document */
	Ext.EventManager.addListener(this.iframeDocument, "mouseup", function()
		{
			widgToolbarCheckState(self);
		}
	);
	
	Ext.EventManager.addListener(this.iframeDocument, "keyup", function(event)
		{
			/* Delay checking of cursor context as keys are pressed -- reduce computation */
			if (typeof window.keyupTimer != "undefined")
			{
				clearTimeout(window.keyupTimer);
			}

			/* Don't allow ctrl-keyups to go through to the check */
			if (event.getKey() != 17)
			{
				window.keyupTimer = setTimeout(function()
					{
						widgToolbarCheckState(self);
					}, 250);
			}
		}
	);
	
	Ext.EventManager.addListener(this.iframeDocument, "keyup", function(event)
		{
			self.detectPaste(event);
		}
	);

	Ext.EventManager.addListener(this.iframeDocument, "keydown", function(event)
		{			
			self.detectShortcuts(event);
		}
	);

	Ext.EventManager.addListener(this.iframeDocument, "keypress", function(event)
		{
			self.handleControlKeys(event);
		}
	);
	
	Ext.EventManager.addListener(this.iframeWindow, "blur", function(event)
		{
			/* To determine when focus is on the editor window and selection boundaries should be deleted upon re-focus */
			if (document.all)
			{
				self.iframeWindow.editorFocus = false;
			}
		}
	);
	
	Ext.EventManager.addListener(this.iframeWindow, "focus", function(event)
		{
			if (document.all)
			{
				self.iframeWindow.editorFocus = true;
			}
		}
	);
	
	this.ready = true;

	return true;	
};




/* Add submit listener to parent form */
widgEditor.prototype.modifyFormSubmit = function()
{
	var self = this;
	var theForm = this.container.parentNode;
	var oldOnsubmit = null;
	
	/* Find the parent form element */
	while (theForm.parentNode != null && theForm.nodeName.toLowerCase() != "form")
	{
		theForm = theForm.parentNode;
	}

	if (theForm.parentNode != null)
	{
		/* Add onsubmit without overwriting existing function calls */
		oldOnsubmit = theForm.onsubmit;
	
		if (typeof theForm.onsubmit != "function")
		{
			theForm.onsubmit = function()
			{
				return self.submit();
			}
		}
		else
		{
			theForm.onsubmit = function()
			{
				self.submit();
	
				return oldOnsubmit();			
			}
		}
	}
	else
	{
		return false;
	}

	return true;
};




/* Add a listener to pre-process submit data */
widgEditor.prototype.addSubmitListener = function(handler)
{
	if (typeof this.submitListeners == "undefined")
	{
		this.submitListeners = [];
	}
	
	this.submitListeners[this.submitListeners.length] = handler;
};




/* Run the listeners to pre-process submit data */
widgEditor.prototype.runSubmitListeners = function()
{
	if (typeof this.submitListeners != "undefined")
	{
		for (var handler in this.submitListeners)
		{
			this.submitListeners[handler]();
		}
	}
}




/* "Submit" the widgEditor; perform some action */
widgEditor.prototype.submit = function()
{
	this.updateWidgInput();
	this.runSubmitListeners();
	this.submitAction();
};




/* Set a function to be executed on a submit() call to the editor */
widgEditor.prototype.setSubmit = function(submitAction)
{
	this.submitAction = submitAction;
};




/* Get the HTML from the editor */
widgEditor.prototype.getHTML = function()
{
	return this.iframeDocument.body.innerHTML;
};




/* Get the value that would be submitted from the editor */
widgEditor.prototype.getSubmitValue = function()
{
	this.updateWidgInput();
	
	var oldInputValue = this.input.value;
	
	this.runSubmitListeners();
	
	var newInputValue = this.input.value;
	this.input.value = oldInputValue;
	
	return newInputValue;
};





/* Format the HTML with paragraphs. Any parentless text is enclosed in a paragraph, double breaks are paragraph markers */
widgEditor.prototype.paragraphise = function(removeEmptyElements)
{
	if (typeof removeEmptyElements == "undefined")
	{
		removeEmptyElements = true;
	}
	
	var theBody = this.iframeWindow.document.getElementsByTagName("body")[0];

	var nextElement = getNextElement(theBody);
	var newParagraph = null;
	
	while (nextElement != null)
	{
		if (!nextElement.nodeName.isBlockName())
		{
			if (newParagraph == null && nextElement.id != "selectionStart" && nextElement.id != "selectionEnd")
			{
				newParagraph = this.iframeWindow.document.createElement("p");
				nextElement.parentNode.insertBefore(newParagraph, nextElement);
			}
			
			if (newParagraph != null)
			{
				newParagraph.appendChild(nextElement);
			}
		}
		else
		{
			newParagraph = null;
		}
			
		nextElement = getNextHigherElement(nextElement);
	}

	if (removeEmptyElements)
	{
//		removeEmpties(theBody);
	}

	return true;
};




/* Update display from hidden input */
widgEditor.prototype.refreshDisplay = function(selectSelection)
{
	/* In case document isn't available yet */
	try
	{
		this.iframeDocument.getElementsByTagName("body")[0].innerHTML = this.input.value;
		
		if (selectSelection)
		{
			selectSelectionBoundaries(this.iframeWindow);
			deleteSelectionBoundaries(this.iframeWindow);
		}
	}
	catch(error)
	{
		var self = this;
		
		setTimeout(function()
			{
				self.refreshDisplay();
			},
			250
		);
	}

	return true;
};




/* Select all content in the editor */
widgEditor.prototype.selectAll = function()
{
	var iframeBody = this.iframeDocument.getElementsByTagName("body")[0];

	var selectionStart = this.iframeDocument.createElement("var");
	selectionStart.id = "selectionStart";
	iframeBody.insertBefore(selectionStart, iframeBody.firstChild);
	
	var selectionEnd = this.iframeDocument.createElement("var");
	selectionEnd.id = "selectionEnd";
	iframeBody.appendChild(selectionEnd);
	
	selectSelectionBoundaries(this.iframeWindow);
	deleteSelectionBoundaries(this.iframeWindow);
	
//	this.focus();
};




/* Get the text of the selected elements */
widgEditor.prototype.getSelectedText = function()
{
	var selectionStart = this.iframeDocument.getElementById("selectionStart");
	
	var text = "";
	
	if (selectionStart != null)
	{
		for (var next = selectionStart; next.id != "selectionEnd"; next = getNextElement(next))
		{
			if (next.nodeType == 3)
			{
				text += next.nodeValue;
			}
		}
	}
	
	text.replace(/\s+/g, " ");
	
	return text;
};




/* Get the HTML of the selected elements */
widgEditor.prototype.getSelectedHTML = function()
{
	var selectionStart = this.iframeDocument.getElementById("selectionStart");
	
	var html = "";
	var cloneContainer = this.iframeDocument.createElement("div");
	
	if (selectionStart != null)
	{
		var next = getNextElement(selectionStart);
		
		for (var next = getNextElement(selectionStart); next.id != "selectionEnd"; next = getNextElement(next))
		{
			cloneContainer.appendChild(next.cloneNode(true));
		}
		
		html = cloneContainer.innerHTML;
	}

	html = cleanSource(html);

	return html;
};




/* Find parent of specified type common to start and end of selection */
widgEditor.prototype.getSelectionParent = function(type)
{
	var selectionStart = this.iframeDocument.getElementById("selectionStart");
	var selectionEnd = this.iframeDocument.getElementById("selectionEnd");
	
	if (selectionStart != null)
	{
		var parent = getCommonParent(selectionStart, selectionEnd);
		
		while (parent != null && typeof parent.nodeName != "undefined")
		{
			if (parent.nodeName.toLowerCase() == type)
			{
				return parent;
			}
			
			parent = parent.parentNode;
		}
	}
	
	return null;
};




/* Select specified element */
widgEditor.prototype.selectElement = function(element)
{
	deleteSelectionBoundaries(this.iframeWindow);
	
	var selectionStart = this.iframeDocument.createElement("var");
	selectionStart.id = "selectionStart";
	element.parentNode.insertBefore(selectionStart, element);
	
	var selectionEnd = this.iframeDocument.createElement("var");
	selectionEnd.id = "selectionEnd";
	Ext.get(selectionEnd).insertAfter(element);	
	
	selectSelectionBoundaries(this.iframeWindow);
};




/* Focus editor */
widgEditor.prototype.focus = function(moveToStart)
{
	if (typeof moveToStart != "undefined" && moveToStart == true)
	{
		if (typeof document.selection != "undefined")
		{
			/* IE doesn't access the body element for a while, so the call has to be repeated in a try/catch */
			try
			{
				var iframeBody = this.iframeDocument.getElementsByTagName("body")[0];
				
				var firstElement = null;
				
				for (var i = 0; i < iframeBody.childNodes.length; i++)
				{
					if (iframeBody.childNodes[i].nodeType == 1)
					{
						firstElement = iframeBody.childNodes[i];
						
						break;
					}
				}
				
				if (firstElement == null)
				{
					firstElement = iframeBody;
				}
			
				var selectionEnd = this.iframeDocument.createElement("var");
				selectionEnd.id = "selectionEnd";
				firstElement.insertBefore(selectionEnd, firstElement.firstChild);
				
				var selectionStart = this.iframeDocument.createElement("var");
				selectionStart.id = "selectionStart";
				firstElement.insertBefore(selectionStart, firstElement.firstChild);
				
				selectSelectionBoundaries(this.iframeWindow);
				deleteSelectionBoundaries(this.iframeWindow);
			}
			catch(error)
			{
				this.blur();
				
				var self = this;
				
				setTimeout(function()
					{
						self.focus(true);
					},
					500
				);
				
				return;
			}
		}
	}
	
	this.iframeWindow.focus();
	selectSelectionBoundaries(this.iframeWindow);
	deleteSelectionBoundaries(this.iframeWindow);	
};




/* Blur editor, doesn't work for Safari */
widgEditor.prototype.blur = function()
{
	window.focus();
};

/* Hide the entire editor from view */
widgEditor.prototype.hide = function()
{
	markSelectionBoundaries(this.iframeWindow);
	this.blur();
	this.updateWidgInput();
	Ext.get(this.container).addClass("widgContainerHidden");
}




/* Show the entire editor (after hiding) */
widgEditor.prototype.show = function()
{
	Ext.get(this.container).removeClass("widgContainerHidden");
	
	if (isSafari)
	{
		this.createIframe();
	}
	
	var self = this;
	
	setTimeout(function()
		{
			try
			{
				selectSelectionBoundaries(self.iframeWindow);
				deleteSelectionBoundaries(self.iframeWindow);
				self.focus(true);
			}
			catch(error)
			{
			}
		},
		1
	);
};




/* Toggle chat mode */
widgEditor.prototype.toggleChatMode = function(toggle)
{
	if (typeof toggle != "undefined")
	{
		this.chatMode = toggle;
	}
	else if (this.chatMode)
	{
		this.chatMode = false;
	}
	else
	{
		this.chatMode = true;
	}
	
	if (this.chatMode)
	{
		Ext.get(this.container).addClass("widgContainerChatMode");
	}
	else
	{
		Ext.get(this.container).removeClass("widgContainerChatMode");
	}
};




/* Update hidden input to reflect editor contents */
widgEditor.prototype.updateWidgInput = function()
{
	//removing the quote div from editor before saving
	var quoteDisableText =  this.iframeDocument.getElementById("quoteDisableText");
	if( !tangler.util.StringUtil.isEmpty(quoteDisableText) )
	{
		try
		{
			this.iframeDocument.getElementsByTagName("body")[0].removeChild(quoteDisableText);
		}
		catch (e) 
		{
			this.iframeDocument.getElementsByTagName("p")[0].removeChild(quoteDisableText);
		}
		this.isQuote = true;
		
	}else
	{
		this.isQuote = false;
	}
	this.paragraphise();
	this.input.value = this.iframeDocument.getElementsByTagName("body")[0].innerHTML;
	
	var cleanedSource = cleanSource(this.input.value);
	
	this.iframeDocument.getElementsByTagName("body")[0].innerHTML = cleanedSource;	
	this.input.value = cleanedSource;
	
	return true;
};

widgEditor.prototype.isQuote = function()
{
	return this.isQuote;
};


/* Write initial content to editor */
widgEditor.prototype.writeDocument = function(documentContent)
{
	/* HTML template into which the HTML Editor content is inserted */
	var documentTemplate = '\
		<html>\
			<head>\
				INSERT:STYLESHEET:END\
			</head>\
			<body id="iframeBody">\
				INSERT:CONTENT:END\
			</body>\
		</html>\
	';
	
	/* Insert dynamic variables/content into document */
	/* IE needs stylesheet to be written inline */
	if (typeof document.all != "undefined")
	{
		documentTemplate = documentTemplate.replace(/INSERT:STYLESHEET:END/, '<link rel="stylesheet" type="text/css" href="' + widgConfig.widgStylesheet + '"></link>');
	}
	/* Firefox can't have stylesheet written inline */
	else
	{
		documentTemplate = documentTemplate.replace(/INSERT:STYLESHEET:END/, "");
	}
	
	documentTemplate = documentTemplate.replace(/INSERT:CONTENT:END/, documentContent);
	
	this.iframeWindow.document.open();
	this.iframeWindow.document.write(documentTemplate);
	this.iframeWindow.document.close();

	/* In Firefox stylesheet needs to be loaded separate to other HTML, because if it's loaded inline it causes Firefox to have problems with an empty document */
	if (typeof document.all == "undefined")
	{
		var stylesheet = this.iframeWindow.document.createElement("link");
		stylesheet.setAttribute("rel", "stylesheet");
		stylesheet.setAttribute("type", "text/css");
		stylesheet.setAttribute("href", widgConfig.widgStylesheet);
		this.iframeWindow.document.getElementsByTagName("head")[0].appendChild(stylesheet);
	}
	
	return true;
};




/* Insert the specified inline HTML */
widgEditor.prototype.insertHTML = function(htmlString)
{
	markSelectionBoundaries(this.iframeWindow);
	deleteSelection(this.iframeWindow);

	var selectionStart = this.iframeDocument.getElementById("selectionStart");

	if (selectionStart != null)
	{
		var newSpan = this.iframeDocument.createElement("span");
		newSpan.innerHTML = htmlString;
		selectionStart.parentNode.insertBefore(newSpan, selectionStart);
	
		/* Remove temporary span, but keep its contents */
		replaceNodeWithChildren(newSpan);
	}
	
	this.focus();
	markSelectionBoundaries(this.iframeWindow);
	selectSelectionBoundaries(this.iframeWindow);
	deleteSelectionBoundaries(this.iframeWindow);

	return true;
};




/* Removes current content from the editor */
widgEditor.prototype.reset = function(content)
{
	if (typeof content == "undefined" || content.match(/^\s*$/))
	{
		if (typeof document.all == "undefined")
		{
			this.input.value = "<br />";
		}
		else
		{
			this.input.value = "";
		}
	}
	else
	{
		this.input.value = content;
	}
	
	var oldToolbarList = this.toolbar.theList;
	
	this.toolbar = new widgToolbar(this, this.toolbarButtons, this.toolbarSelects);
	this.container.replaceChild(this.toolbar.theList, oldToolbarList);

	this.refreshDisplay();
};




/* Checks whether the editor is ready to receive commands */
widgEditor.prototype.isReady = function()
{
	return this.ready;
};




/* Toolbar items */
function widgToolbar(editor, toolbarButtons, toolbarSelects)
{
	var self = this;
	
	this.editor = editor;
	
	/* Create toolbar ul element */
	this.theList = document.createElement("ul");
	this.theList.id = this.editor.input.id + "WidgToolbar";
	this.theList.className = "widgToolbar";
	this.theList.widgToolbarObject = this;

	/* Create toolbar items */
	for (var i = 0; i < toolbarButtons.length; i++)
	{
		this.addButton(toolbarButtons[i]);
	}
	
	return true;
};





/* Add button to toolbar */
widgToolbar.prototype.addButton = function(button)
{
	if (typeof button == "string")
	{
		this.addPlugin(button);
	}
	else
	{
		var menuItem = document.createElement("li");
		menuItem.id = this.theList.id + button.className;
		menuItem.className = "widgEditButton " + button.className;

			var input = document.createElement("input");
			input.type = "image";
			input.alt = button.title;
			input.title = button.title;
			input.src = button.image;
			input.genericOnclickHandler = onclickToolbarButton;
			input.onclickHandler = button.action;
			input.onclick = function()
			{
				if (this.genericOnclickHandler())
				{
					return this.onclickHandler();
				}
				else
				{
					return false;
				}
			};

			input.onmousedown = onmousedownButton;
			input.onmouseover = onmouseoverButton;
			input.onmouseout = onmouseoutButton;
			menuItem.appendChild(input);

		this.theList.appendChild(menuItem);
		
		return menuItem;
	}

	return true;
};




widgToolbar.prototype.addPlugin = function(plugin)
{
	var self = this;
	var pluginCapitalised = plugin.substring(0, 1).toUpperCase() + plugin.substring(1, plugin.length);
	var className = "widgButton" + pluginCapitalised;
	var image = widgConfig.pluginsPath + "/" + plugin + "/button.gif";
	var standinFunction = function()
	{
		alert("This plugin has not yet loaded");
		
		return false;
	};
			
	var menuItem = this.addButton(
		{
			className: className,
			title: plugin,
			action: standinFunction,
			image: image
		}
	);
	var input = menuItem.getElementsByTagName("input")[0];
	
	// Checks whether all components of the plugin have been loaded, then executes the plugin's JavaScript
	var checkReady = function()
	{
		var editor = self.editor;
		var pluginData = widgPlugins[plugin];
		
		if (typeof pluginData != "undefined" && typeof pluginData.description != "undefined" && typeof pluginData.html != "undefined" && typeof pluginData.js != "undefined")
		{
			if (editor.ready)
			{
				input.alt = pluginData.description.title;
				input.title = pluginData.description.title;
	
				var newDivId = editor.id + "widgPlugin" + pluginCapitalised;
				var existingDiv = document.getElementById(newDivId)
				
				if (existingDiv != null)
				{
					existingDiv.parentNode.removeChild(existingDiv);
				}

				var newDiv = document.createElement("div");
				newDiv.id = newDivId;
				newDiv.innerHTML = pluginData.html.replace(/(id="[^"]+)"/g, "$1" + editor.id + '"');
				document.getElementsByTagName("body")[0].appendChild(newDiv);
	
				// Closure for access to editor from plugin
				eval(widgPlugins[plugin].js);
				
				input.onclickHandler = function()
				{
					markSelectionBoundaries(editor.iframeWindow);
					selectSelectionBoundaries(editor.iframeWindow);
	
					return eval(pluginData.description.action)(this);
				};
			}
			else
			{
				setTimeout(function()
					{
						checkReady();
					},
					100
				);
			}
		}
	};

	if (typeof widgPlugins[plugin] == "undefined")
	{
		widgPlugins[plugin] = {};
		widgPlugins[plugin].ready = false;
		
		var pluginData = widgPlugins[plugin];
		
		var descriptionConnection = new Ext.data.Connection();
		descriptionConnection.request(
			{
				url: widgConfig.pluginsPath + plugin + "/description.js",
				callback: function(options, success, response)
					{
						// Creates variable "description"
						eval(response.responseText);
						
						pluginData.description = description;
						
						checkReady();
					}
			}
		);
		
		var templateConnection = new Ext.data.Connection();
		templateConnection.request(
			{
				url: widgConfig.pluginsPath + plugin + "/template.htm",
				callback: function(options, success, response)
					{
						pluginData.html = response.responseText;
						
						checkReady();
					}
			}
		);
		
		var behaviourConnection = new Ext.data.Connection();
		behaviourConnection.request(
			{
				url: widgConfig.pluginsPath + plugin + "/behaviour.js",
				callback: function(options, success, response)
					{
						pluginData.js = response.responseText;
						
						checkReady();
					}
			}
		);
	}
	
	checkReady();
};




/* Change the status of the selected toolbar item */
widgToolbar.prototype.setState = function(theItem, theStatus, targetElement)
{
	var theButton = document.getElementById(this.theList.id + theItem);

	if (theButton != null)
	{
		if (theStatus == "on")
		{
			Ext.get(theButton).addClass("on");

			if (typeof targetElement != "undefined")
			{
				theButton.targetElement = targetElement;
			}
		}
		else
		{
			Ext.get(theButton).removeClass("on");
			
			theButton.targetElement = null;
		}
	}
			
	return true;	
};




/* Check the nesting of the current cursor position/selection */
function widgToolbarCheckState(editor, resubmit)
{
	if (editor.cancelToolbarCheck == true)
	{
		editor.cancelToolbarCheck = false;
		
		return true;
	}
			
	if (typeof resubmit == "undefined")
	{
		setTimeout(function()
			{
				widgToolbarCheckState(editor, true);
			}, 500);
	}
	
	try
	{
		var theSelection = new selectionObj(editor.iframeWindow);
	}
	catch(error)
	{
		return false;
	}

	if (theSelection.selection == null || theSelection.textRange == null)
	{
		return false;
	}

	var theParentNode = null;
	
	/* Turn off all the buttons */
	var menuListItems = editor.toolbar.theList.childNodes;
	for (var i = 0; i < menuListItems.length; i++)
	{
		Ext.get(menuListItems[i]).removeClass("on");
	}
	
	/* IE image selected */
	if (document.selection)
	{
		if (theSelection.selection.type == "Control" && theSelection.textRange.length == 1 && theSelection.textRange.item(0).nodeName.toLowerCase() == "img")
		{
			if (Ext.get(theSelection.textRange.item(0)).hasClass("widgImageLeft"))
			{
				editor.toolbar.setState("widgButtonImageLeft", "on");
			}
			else if (Ext.get(theSelection.textRange.item(0)).hasClass("widgImageRight"))
			{
				editor.toolbar.setState("widgButtonImageRight", "on");
			}
		}
	}
	/* Mozilla image selected */
	else
	{
		var clonedContents = theSelection.textRange.cloneContents();
		
		if (clonedContents != null && clonedContents.childNodes.length == 1 && clonedContents.firstChild.nodeName.toLowerCase() == "img")
		{
			if (Ext.get(clonedContents.firstChild).hasClass("widgImageLeft"))
			{
				editor.toolbar.setState("widgButtonImageLeft", "on");
			}
			else if (Ext.get(clonedContents.firstChild).hasClass("widgImageRight"))
			{
				editor.toolbar.setState("widgButtonImageRight", "on");
			}
		}
	}
	
	/* IE selections */
	if (typeof theSelection.textRange.parentElement != "undefined")
	{
		theParentNode = theSelection.textRange.parentElement();
	}
	/* Mozilla/Safari selections */
	else if (typeof theSelection.textRange.commonAncestorContainer != "undefined")
	{
		theParentNode = theSelection.textRange.commonAncestorContainer;
		
		if (theParentNode.nodeName.toLowerCase() == "#document")
		{
			return false;
		}
	}
	else
	{
		return false;
	}
	
	var styleSet = false;

	while (!theParentNode.nodeName.isBlockName())
	{
		switch (theParentNode.nodeName.toLowerCase())
		{
			case "a":
				editor.toolbar.setState("widgButtonHyperlink", "on", theParentNode);
				
				break;
				
			case "del":
				editor.toolbar.setState("widgButtonStrikethrough", "on", theParentNode);
				
				break;
				
			case "em":
				editor.toolbar.setState("widgButtonItalic", "on", theParentNode);
				
				break;
				
			case "strong":
				editor.toolbar.setState("widgButtonBold", "on", theParentNode);
				
				break;
				
			case "u":
				editor.toolbar.setState("widgButtonUnderline", "on", theParentNode);
				
				break;
		}
	
		if (!styleSet)
		{
			var theSelect = document.getElementById(editor.toolbar.theList.id + "widgSelectStyle");

			if (theSelect != null)
			{
				for (var i = 0; i < theSelect.options.length; i++)
				{
					if (typeof theParentNode.className != "undefined" && Ext.get(theParentNode).hasClass(theSelect.options[i].value))
					{
						styleSet = true;
						editor.toolbar.setState("widgSelectStyle", theSelect.options[i].value);
					}
				}
			}
		}

		theParentNode = theParentNode.parentNode;
	}
	
	if (!styleSet)
	{
		var theSelect = document.getElementById(editor.toolbar.theList.id + "widgSelectStyle");

		if (theSelect != null)
		{
			for (var i = 0; i < theSelect.options.length; i++)
			{
				if (Ext.get(theParentNode).hasClass(theSelect.options[i].value))
				{
					styleSet = true;
					editor.toolbar.setState("widgSelectStyle", theSelect.options[i].value);
				}
			}
		}
	}
	
	if (!styleSet)
	{
					editor.toolbar.setState("widgSelectStyle", "");
	}

	switch (theParentNode.nodeName.toLowerCase())
	{
		case "blockquote":
			editor.toolbar.setState("widgButtonBlockquote", "on");

			break;

		case "li":
			if (theParentNode.parentNode.nodeName.toLowerCase() == "ol")
			{
				editor.toolbar.setState("widgButtonOrdered", "on");
			}
			else
			{
				editor.toolbar.setState("widgButtonUnordered", "on");
			}

			editor.toolbar.setState("widgSelectBlock", "");
			
			break;

		default:
			editor.toolbar.setState("widgSelectBlock", theParentNode.nodeName.toLowerCase());

			break;
	}
	
	/* Possible to have a block element inside a blockquote */	
	if (theParentNode.parentNode != null && theParentNode.parentNode.nodeName.toLowerCase() == "blockquote")
	{
		editor.toolbar.setState("widgButtonBlockquote", "on");
	}
		
	return true;			
};




/******************************************************************************/
/* EVENT HANDLERS */
/******************************************************************************/

function onclickBold()
{
	if (Ext.get(this.parentNode).hasClass("on"))
	{
		removeInlineElement("strong", this.parentNode.parentNode.widgToolbarObject.editor);

		this.parentNode.parentNode.widgToolbarObject.setState("widgButtonBold", "off");
	}
	else
	{
		if (insertInlineElement("strong", this.parentNode.parentNode.widgToolbarObject.editor))
		{
			this.parentNode.parentNode.widgToolbarObject.setState("widgButtonBold", "on");
		}
	}
	var quoteDisableText = this.parentNode.parentNode.widgToolbarObject.editor.iframeDocument.getElementById("quoteDisableText");
	if( quoteDisableText != null )
	{
		try
		{
			var strongTag = this.parentNode.parentNode.widgToolbarObject.editor.iframeDocument.getElementsByTagName("strong")[0];
			var pTag = this.parentNode.parentNode.widgToolbarObject.editor.iframeDocument.getElementsByTagName("p")[0];
			this.parentNode.parentNode.widgToolbarObject.editor.iframeDocument.getElementsByTagName("p")[0].removeChild(quoteDisableText);
			this.parentNode.parentNode.widgToolbarObject.editor.iframeDocument.getElementsByTagName("body")[0].insertBefore(quoteDisableText,pTag);
		}
		catch (e) {}
		
	}
	return false;
};




function onclickItalic()
{
	if (Ext.get(this.parentNode).hasClass("on"))
	{
		removeInlineElement("em", this.parentNode.parentNode.widgToolbarObject.editor);
		
		this.parentNode.parentNode.widgToolbarObject.setState("widgButtonItalic", "off");
	}
	else
	{
		if (insertInlineElement("em", this.parentNode.parentNode.widgToolbarObject.editor))
		{
			this.parentNode.parentNode.widgToolbarObject.setState("widgButtonItalic", "on");
		}
	}
	
	return false;
};




function onclickOrderedList()
{
	var toolbar = this.parentNode.parentNode.widgToolbarObject;
	var editor = toolbar.editor;
	
	var quoteDisableText = editor.iframeDocument.getElementById("quoteDisableText");
	
	editor.iframeDocument.execCommand("insertorderedlist", false, null);
	
	if( quoteDisableText != null )
	{
		try
		{
			var ulTag = editor.iframeDocument.getElementsByTagName("li")[0];
			ulTag.removeChild(quoteDisableText);
			editor.iframeDocument.getElementsByTagName("body")[0].insertBefore(quoteDisableText,editor.iframeDocument.getElementsByTagName("ol")[0]);
		}
		catch (e) {}
		
	}

	editor.toolbar.setState("widgButtonUnordered", "off");

	if (editor.iframeDocument.queryCommandState("insertorderedlist", false, null))
	{
		editor.toolbar.setState("widgButtonOrdered", "on");
		editor.toolbar.setState("widgSelectBlock", "");
	}
	else
	{
		editor.toolbar.setState("widgButtonOrdered", "off");
	}
	
	return false;
};




function onclickStrikethrough()
{
	if (Ext.get(this.parentNode).hasClass("on"))
	{
		removeInlineElement("del", this.parentNode.parentNode.widgToolbarObject.editor);
		
		this.parentNode.parentNode.widgToolbarObject.setState("widgButtonStrikethrough", "off");
	}
	else
	{
		if (insertInlineElement("del", this.parentNode.parentNode.widgToolbarObject.editor))
		{
			this.parentNode.parentNode.widgToolbarObject.setState("widgButtonStrikethrough", "on");
		}
	}
	
	return false;
};




function onclickToolbarButton()
{
	if (!Ext.get(this.parentNode.parentNode).hasClass("widgSource") || Ext.get(this).hasClass("widgButtonHTML"))
	{
		try
		{
			this.parentNode.parentNode.widgToolbarObject.editor.iframeWindow.focus();
		}
		catch (error)
		{
		}
	
		return true;
	}
	
	return false;
};




function onclickUnderline()
{
	if (Ext.get(this.parentNode).hasClass("on"))
	{
		removeInlineElement("u", this.parentNode.parentNode.widgToolbarObject.editor);

		this.parentNode.parentNode.widgToolbarObject.setState("widgButtonUnderline", "off");
	}
	else
	{
		if (insertInlineElement("u", this.parentNode.parentNode.widgToolbarObject.editor))
		{
			this.parentNode.parentNode.widgToolbarObject.setState("widgButtonUnderline", "on");
		}
	}
	
	return false;
};




function onclickUnorderedList(event)
{
	var toolbar = this.parentNode.parentNode.widgToolbarObject;
	var editor = toolbar.editor;
	
	var quoteDisableText = editor.iframeDocument.getElementById("quoteDisableText");
	
	editor.iframeDocument.execCommand("insertunorderedlist", false, null);
	if( quoteDisableText != null )
	{
		try
		{
			var ulTag = editor.iframeDocument.getElementsByTagName("li")[0];
			ulTag.removeChild(quoteDisableText);
			editor.iframeDocument.getElementsByTagName("body")[0].insertBefore(quoteDisableText,editor.iframeDocument.getElementsByTagName("ul")[0]);
		}
		catch (e) {}
		
	}

	editor.toolbar.setState("widgButtonOrdered", "off");

	if (editor.iframeDocument.queryCommandState("insertunorderedlist", false, null))
	{
		editor.toolbar.setState("widgButtonUnordered", "on");
		editor.toolbar.setState("widgSelectBlock", "");
	}
	else
	{
		editor.toolbar.setState("widgButtonUnordered", "off");
	}
	
	return false;
};




function onmousedownButton()
{
	return false;
};




function onmouseoverButton()
{
	window.status = "";
	Ext.get(this).addClass("hover");
	
	return true;
};




function onmouseoutButton()
{
	Ext.get(this).removeClass("hover");

	return true;
};




/******************************************************************************/
/* DOM FUNCTIONS */
/******************************************************************************/

/* Remove invalid elements, but keep their contents */
function acceptableChildren(theNode)
{
	var theChildren = theNode.childNodes;
	
	for (var i = 0; i < theChildren.length; i++)
	{
		if (!theChildren[i].nodeName.isAcceptedElementName())
		{
			if (!theChildren[i].nodeName.isInlineName())
			{
				if (theNode.nodeName.toLowerCase() == "p")
				{
					acceptableChildren(replaceNodeWithChildren(theNode).parentNode);
					
					return true;
				}
				
				changeNodeType(theChildren[i], "p");
			}
			else
			{
				replaceNodeWithChildren(theChildren[i]);
			}
				
			i = -1;
		}
	}
	
	for (var i = 0; i < theChildren.length; i++)
	{
		acceptableChildren(theChildren[i]);
	}
	
	return true;
};




/* Change the type of a node, e.g. h3 to p */
function changeNodeType(theNode, nodeType)
{
	var documentPointer = theNode.ownerDocument;
	
	if (typeof documentPointer != "undefined")
	{
		var theNewNode = documentPointer.createElement(nodeType);
		var theParent = theNode.parentNode;
		
		if (theParent != null)
		{
			for (var i = 0; i < theNode.childNodes.length; )
			{
				theNewNode.appendChild(theNode.childNodes[i]);
			}
			
			theParent.replaceChild(theNewNode, theNode);
		}
	}
	
	return true;
};




/* Get next element in the source code, traversing children and parent nodes */
function getNextElement(currElement, boolGetTextNodes)
{
	try
	{
		var nextElement = null;

		if (currElement.childNodes.length > 0)
		{
			nextElement = currElement.childNodes[0];
		}
		else if (currElement.nextSibling != null)
		{
			nextElement = currElement.nextSibling;
		}
		else
		{
			while (currElement.parentNode != null)
			{
				currElement = currElement.parentNode;

				if (currElement.nextSibling != null)
				{
					nextElement = currElement.nextSibling;

					break;
				}
			}
		}

		if (typeof boolGetTextNodes != "undefined" && boolGetTextNodes == false && nextElement != null && nextElement.nodeType == "3")
		{
			return getNextElement(nextElement, false);
		}

		return nextElement;
	}
	catch(error)
	{
		return null;
	}
};




/* Get previous element in the source code, traversing children and parent nodes */
function getPreviousElement(currElement, boolGetTextNodes)
{
	try
	{
		var previousElement = null;

		if (currElement.previousSibling != null)
		{
			previousElement = currElement.previousSibling;

			while (previousElement.childNodes.length > 0)
			{
				previousElement = previousElement.childNodes[previousElement.childNodes.length - 1];
			}
		}
		else if (currElement.parentNode != null)
		{
			previousElement = currElement.parentNode;
		}

		if (typeof boolGetTextNodes != "undefined" && boolGetTextNodes == false && previousElement != null && previousElement.nodeType == "3")
		{
			return getNextElement(previousElement, false);
		}

		return previousElement;
	}
	catch(error)
	{
		return null;
	}
};




/* Get next element in the source code that is on the same level or higher than the current */
function getNextHigherElement(currElement, boolGetTextNodes)
{
	try
	{
		var nextElement = null;

		if (currElement.nextSibling != null)
		{
			nextElement = currElement.nextSibling
		}
		else
		{
			while (currElement.parentNode != null)
			{
				currElement = currElement.parentNode;

				if (currElement.nextSibling != null)
				{
					nextElement = currElement.nextSibling;

					break;
				}
			}
		}

		if (typeof boolGetTextNodes != "undefined" && boolGetTextNodes == false && nextElement.nodeType == "3")
		{
			return getNextHigherElement(nextElement, false);
		}

		return nextElement;
	}
	catch(error)
	{
		return null;
	}
};



/* Determine whether an element only contains blank or whitespace text nodes */
function isEmptyElement(target, excludeVar)
{
	if (typeof excludeVar == "undefined")
	{
		excludeVar = false;
	}

	if (target.nodeType == 1 && !target.nodeName.isValidEmpty() && ((excludeVar == false && target.id != "selectionStart" && target.id != "selectionEnd") || excludeVar == true) && !target.innerHTML.match(/&nbsp;|\xA0/))
	{
		if (target.childNodes.length > 0)
		{
			for (var i = 0; i < target.childNodes.length; i++)
			{
				if (!isEmptyElement(target.childNodes[i], excludeVar))
				{
					return false;
				}
			}
			
			return true;
		}
		else
		{
			return true;
		}
	}
	else if (target.nodeType == 3 && (target.nodeValue == null || target.nodeValue == "" || target.nodeValue.match(/^\s+$/) != null))
	{
		return true;
	}
	
	return false;
};




/* Create HTML markers around the current selection */
function markSelectionBoundaries(windowRef)
{
	if (typeof windowRef.editorFocus == "undefined" && !isSafari || (typeof windowRef.editorFocus != "undefined" && windowRef.editorFocus === true))
	{
		deleteSelectionBoundaries(windowRef);
	}

	try
	{
		/* Mozilla/Safari selection handling */	
		if (typeof windowRef.getSelection == "function")
		{
			var selection = windowRef.getSelection();

			/* Mozilla text range handling */
			if (typeof selection.getRangeAt == "function" && selection.rangeCount > 0)
			{
				var textRange = selection.getRangeAt(0).cloneRange();
			}

			/* Safari text range handling */
			else if (typeof selection.baseNode != "undefined")
			{
				/* Create a range from the end nodes to see whether the baseNode is after the extentNode i.e. the selection is from right to left */
				var textRange = windowRef.document.createRange();

				textRange.setStart(selection.baseNode, selection.baseOffset);
				textRange.setEnd(selection.extentNode, selection.extentOffset);

				if (textRange.collapsed)
				{
					textRange.setEnd(selection.baseNode, selection.baseOffset);
					textRange.setStart(selection.extentNode, selection.extentOffset);
				}
			}

			/* If selection starts and ends inside the same text node */			
			if ((typeof selection.baseNode != "undefined" && selection.baseNode == selection.extentNode && selection.baseNode.nodeType == 3) || (typeof selection.anchorNode != "undefined" && selection.anchorNode == selection.focusNode && selection.anchorNode.nodeType == 3))
			{
				var textContent = textRange.extractContents();

				var selectionEnd = windowRef.document.createElement("var");
				selectionEnd.setAttribute("id", "selectionEnd");
				textRange.insertNode(selectionEnd);
				
				var selectionStart = windowRef.document.createElement("var");
				selectionStart.setAttribute("id", "selectionStart");
				selectionEnd.parentNode.insertBefore(selectionStart, selectionEnd);
				
				if (textContent != null)
				{
					selectionEnd.parentNode.insertBefore(textContent, selectionEnd);
				}
				
				var emptyNode = selectionStart.nextSibling;
				
				/* Remove text nodes with no content (not even whitespace) */
				while(emptyNode != null && emptyNode != selectionEnd && emptyNode.nodeType == 3 && emptyNode.data == "")
				{
					emptyNode = emptyNode.nextSibling;
					emptyNode.parentNode.removeChild(emptyNode.previousSibling);
				}
			}
			else
			{
				if (textRange.collapsed)
				{
					var newVar = windowRef.document.createElement("var");
					newVar.setAttribute("id", "selectionEnd");
					textRange.insertNode(newVar);

					var newVar = windowRef.document.createElement("var");
					newVar.setAttribute("id", "selectionStart");
					textRange.insertNode(newVar);
				}
				else
				{
					var newVar = windowRef.document.createElement("var");
					newVar.setAttribute("id", "selectionStart");
					var textRangeCopy = textRange.cloneRange();
					textRangeCopy.collapse(true);
					textRangeCopy.insertNode(newVar);

					var newVar = windowRef.document.createElement("var");
					newVar.setAttribute("id", "selectionEnd");
					var textRangeCopy = textRange.cloneRange();
					textRangeCopy.collapse(false);
					textRangeCopy.insertNode(newVar);
				}
			}
		}
		/* Internet Explorer selection handling */
		else if (typeof windowRef.document.selection != "undefined")
		{
			var selection = windowRef.document.selection;
			var textRange = selection.createRange();

			var startRange = selection.createRange();
			var endRange = selection.createRange();

			if (selection.type == "Control")
			{
				if (textRange.length == 1 && textRange.item(0).nodeName.toLowerCase() == "img")
				{
					var newVar = windowRef.document.createElement("var");
					newVar.setAttribute("id", "selectionStart");
					textRange.item(0).parentNode.insertBefore(newVar, textRange.item(0));

					var newVar = windowRef.document.createElement("var");
					newVar.setAttribute("id", "selectionEnd");
					Ext.get(newVar).insertAfter(textRange.item(0));
				}
			}
			else if (selection.type != "None")
			{
				/* Set range copies to start and end of selection, to determine parent nodes at either end */
				startRange.collapse(true);
				endRange.collapse(false);
				startRange.pasteHTML('<var id="selectionStart"></var>');
				endRange.pasteHTML('<var id="selectionEnd"></var>');
			}
			else
			{
				startRange.pasteHTML('<var id="selectionStart"></var><var id="selectionEnd"></var>');
			}
		}
		
		var selectionStart = windowRef.document.getElementById("selectionStart");
		var selectionEnd = windowRef.document.getElementById("selectionStart");

		/* Remove empty text nodes from between selection */		
		if (selectionStart != null && selectionEnd != null)
		{
			var nextElement = getNextHigherElement(selectionStart);
			
			while (nextElement.nodeType == 3 || nextElement.id != "selectionEnd")
			{
				if (nextElement.nodeType == 3 && nextElement.nodeValue == "")
				{
					var previousElement = nextElement;
					nextElement = getNextElement(nextElement);
					previousElement.parentNode.removeChild(previousElement);
				}
				else
				{
					nextElement = getNextElement(nextElement);
				}
			}
		}
	}
	catch (error)
	{
		var selectionStart = windowRef.document.getElementById("selectionStart");
		var selectionEnd = windowRef.document.getElementById("selectionEnd");
		
		if (selectionStart  == null && selectionEnd == null)
		{
			deleteSelectionBoundaries(windowRef);
			
			var newVar = windowRef.document.createElement("var");
			newVar.setAttribute("id", "selectionStart");
			windowRef.document.body.appendChild(newVar);
	
			newVar = windowRef.document.createElement("var");
			newVar.setAttribute("id", "selectionEnd");
			windowRef.document.body.appendChild(newVar);
		}

		return false;
	}
	
	return true;
};




/* Create a selection from the current HTML selection markers */
function selectSelectionBoundaries(windowRef)
{
	var varNodes = windowRef.document.getElementsByTagName("var");
	var selectionStart = null;
	var selectionEnd = null;

	for (var i = 0; i < varNodes.length; i++)
	{
		if (varNodes[i].id == "selectionStart")
		{
			selectionStart = varNodes[i];
		}
		
		if (varNodes[i].id == "selectionEnd")
		{
			selectionEnd = varNodes[i];
		}
	}
	
	if (selectionStart == null || selectionEnd == null)
	{
		return false;
	}
	
	/* FF & Safari */	
	if (typeof windowRef.getSelection == "function")
	{
		var selection = windowRef.getSelection();
		var textRange = windowRef.document.createRange();
		
		try
		{
			textRange.setStartAfter(selectionStart);
			textRange.setEndBefore(selectionEnd);
		}
		catch(error)
		{
		}
		
		/* Set Mozilla selection */
		if (typeof selection.removeAllRanges != "undefined")
		{
			selection.removeAllRanges();
			selection.addRange(textRange);
		}
		/* Safari */
		else if (typeof selection.setBaseAndExtent != "undefined")
		{
			selection.setBaseAndExtent(selectionStart, 0, selectionEnd, 0);
		}
	}
	else if (typeof windowRef.document.selection != "undefined")
	{
		var body = windowRef.document.getElementsByTagName("body")[0];
		var textRange = body.createTextRange();
		var endRange = body.createTextRange();

		/* IE needs *some* content to make a selection */
		if (selectionStart.nextSibling == selectionEnd)
		{
			try
			{
				selectionStart.innerHTML = "&nbsp;";
			}
			catch(error)
			{
			}
		}

		textRange.moveToElementText(selectionStart);
		endRange.moveToElementText(selectionEnd);
		textRange.setEndPoint("EndToStart", endRange);
		
		if (selectionStart.nextSibling == selectionEnd)
		{
			endRange.select();
		}
		else
		{
			textRange.select();
		}
		
		selectionStart.innerHTML = "";
	}
	
	return true;
};




/* Delete the content between HTML selection markers */
function deleteSelection(windowRef)
{
	var selectionStart = windowRef.document.getElementById("selectionStart");
	var selectionEnd = windowRef.document.getElementById("selectionEnd");
	
	var nextElement = getNextHigherElement(selectionStart);

	while (nextElement != null && nextElement.id != "selectionEnd")
	{
		// Safe to remove node if selectionEnd isn't a descendant
		if (!isDescendantNode(selectionEnd, nextElement))
		{
			var currElement = nextElement;
			nextElement = getNextHigherElement(nextElement);
			currElement.parentNode.removeChild(currElement);
		}
		else
		{
			nextElement = getNextElement(nextElement);
		}
	}
	
	if (nextElement != null)
	{
		Ext.get(selectionEnd).insertAfter(selectionStart);
	}
	
	return true;
};




/* Remove HTML selection markers */
function deleteSelectionBoundaries(windowRef)
{
	var varNodes = windowRef.document.getElementsByTagName("var");
	
	for (var i = 0; i < varNodes.length; i++)
	{
		if (varNodes[i].id == "selectionStart" || varNodes[i].id == "selectionEnd")
		{
			varNodes[i].parentNode.removeChild(varNodes[i]);

			i--;
		}
	}
	
	return true;
};




/* Remove ids from HTML selection markers (alternative to deleting them, so that the cursor doesn't disappear in FF) */
function nullifySelectionBoundaries(windowRef)
{
	var varNodes = windowRef.document.getElementsByTagName("var");
	
	for (var i = 0; i < varNodes.length; i++)
	{
		if (varNodes[i].id == "selectionStart" || varNodes[i].id == "selectionEnd")
		{
			varNodes[i].id = "";
		}
	}
	
	return true;
};




/* Get parent common to two elements */
function getCommonParent(element1, element2)
{
	startParent = element1.parentNode;
	
	while (startParent != null)
	{
		var endParent = element2.parentNode;

		while (endParent != null)
		{
			if (endParent == startParent)
			{
				break;
			}

			endParent = endParent.parentNode;
		}

		if (endParent == startParent)
		{
			break;
		}

		startParent = startParent.parentNode;
	}
	
	return startParent;
};




/* Wrap the current selection inside the specified inline tag type */
function insertInlineElement(elementName, editor, attributes)
{
	if (editor.iframeDocument.getElementById("selectionStart") == null)
	{
		markSelectionBoundaries(editor.iframeWindow)
	}
	
	editor.paragraphise();

	var selectionStart = editor.iframeDocument.getElementById("selectionStart");
	var selectionEnd = editor.iframeDocument.getElementById("selectionEnd");

	/* No selection made */
	if (selectionEnd == selectionStart.nextSibling)
	{
		var newInline = createElement(editor.iframeWindow, elementName, attributes);
		selectionStart.parentNode.insertBefore(newInline, selectionStart);
		newInline.appendChild(selectionStart);
		newInline.appendChild(selectionEnd);
	}
	else
	{
		var nextElement = getNextElement(selectionStart);
	
		/* Remove all fully selected elements that are the same as the to-be-inserted element */
		while (nextElement.id != "selectionEnd")
		{
			if (nextElement.nodeType != "3" && !isDescendantNode(selectionEnd, nextElement) && nextElement.nodeName.toLowerCase() == elementName)
			{
				currElement = nextElement;
				nextElement = getPreviousElement(nextElement);
	
				replaceNodeWithChildren(currElement);
			}
			else
			{					
				nextElement = getNextElement(nextElement);
			}
		}
	
		var nextElement = getNextElement(selectionStart);
	
		/* Replace any initial text nodes with an enclosing inline element */
		if (nextElement.nodeType == "3")
		{
			var newInline = createElement(editor.iframeWindow, elementName, attributes);
	
			while (nextElement.id != "selectionEnd" && isDescendantNode(nextElement, selectionStart.parentNode) && !isDescendantNode(selectionEnd, nextElement))
			{
				currElement = nextElement;
				nextElement = getNextElement(nextElement);
	
				newInline.appendChild(currElement);
			}
	
			newInline = selectionStart.parentNode.insertBefore(newInline, selectionStart);
			newInline.parentNode.insertBefore(selectionStart, newInline);
		}
	
		/* For elements that are selected but do not contain the end node, wrap in inline element */
		while (nextElement.id != "selectionEnd")
		{
			if (!isDescendantNode(selectionEnd, nextElement))
			{
				if (nextElement.nodeName.isBlockName())
				{
					nextElement = getNextElement(nextElement);
				}
	
				var newInline = createElement(editor.iframeWindow, elementName, attributes);
	
				nextElement.parentNode.insertBefore(newInline, nextElement);
	
				while (nextElement.id != "selectionEnd" && !nextElement.nodeName.isBlockName() && !isDescendantNode(selectionEnd, nextElement))
				{
					currElement = nextElement;
					nextElement = getNextHigherElement(nextElement);
	
					newInline.appendChild(currElement);
				}
			}
			else
			{
				nextElement = getNextElement(nextElement);
			}
		}
	
		var blockParent = selectionStart.parentNode;
	
		while (!blockParent.nodeName.isBlockName())
		{
			blockParent = blockParent.parentNode;
		}
	
		var parentFirstChild = getNextElement(blockParent);
	
		var nextElement = parentFirstChild;
	
		/* Clean up nested elements */
		while (nextElement != null && !nextElement.nodeName.isBlockName())
		{
			var currElement = nextElement;
	
			if (currElement.nodeName.toLowerCase() == elementName)
			{
				/* Detect if current element has parent that is the same as the inline element that was added */
				while (currElement.parentNode != null)
				{
					if (currElement.parentNode.nodeName.toLowerCase() == elementName)
					{
						currElement = nextElement;
						nextElement = getPreviousElement(nextElement);
						replaceNodeWithChildren(currElement);
	
						break;
					}
					else
					{
						currElement = currElement.parentNode;
					}
				}
			}
	
			nextElement = getNextElement(nextElement);
		}
	
		var nextElement = parentFirstChild;
	
		/* Clean up adjoining identical elements */
		while (nextElement != null && !nextElement.nodeName.isBlockName())
		{
			if (nextElement.nodeName.toLowerCase() == elementName && nextElement.nextSibling != null)
			{
				var nextHigher = nextElement.nextSibling;
	
				while ((nextHigher.id == "selectionStart" || nextHigher.id == "selectionEnd") && nextHigher.nextSibling != null)
				{
					nextHigher = nextHigher.nextSibling;
				}
	
				/* Detect if next element has next sibling that is the same as the inline element that was added, then merge */
				if (nextHigher.nodeName.toLowerCase() == elementName)
				{
					while (nextHigher.previousSibling != nextElement)
					{
						nextElement.appendChild(nextHigher.previousSibling);
					}
	
					nextHigher = nextElement.appendChild(nextHigher);
					replaceNodeWithChildren(nextHigher);
				}
				else
				{
					nextElement = getNextElement(nextElement);
				}
			}
			else
			{
				nextElement = getNextElement(nextElement);
			}
		}
	
		/* Refresh selection marker references */
		selectionStart = editor.iframeDocument.getElementById("selectionStart");
		selectionEnd = editor.iframeDocument.getElementById("selectionEnd");
	
		removeEmpties(getCommonParent(selectionStart, selectionEnd));
	}

	selectSelectionBoundaries(editor.iframeWindow);
	nullifySelectionBoundaries(editor.iframeWindow);
	
	return true;
};




/* Remove any of the specified inline tag type from the selection */
function removeInlineElement(elementName, editor)
{
	if (editor.iframeDocument.getElementById("selectionStart") == null)
	{
		markSelectionBoundaries(editor.iframeWindow)
	}
	
	editor.paragraphise();

	var selectionStart = editor.iframeDocument.getElementById("selectionStart");
	var selectionEnd = editor.iframeDocument.getElementById("selectionEnd");

	var nextElement = getNextElement(selectionStart);

	/* Remove all fully selected elements that are the same as the specified element */
	while (nextElement.id != "selectionEnd")
	{
		if (nextElement.nodeName.toLowerCase() == elementName)
		{
			var currElement = nextElement;
			nextElement = getPreviousElement(nextElement);

			replaceNodeWithChildren(currElement);
		}
		else
		{					
			nextElement = getNextElement(nextElement);
		}
	}

	/* Remove any immediately enclosing elements that are the same as the specified */
	if (selectionStart.parentNode.nodeName.toLowerCase() == elementName && selectionStart == selectionStart.parentNode.firstChild && selectionEnd.parentNode == selectionStart.parentNode && selectionEnd == selectionEnd.parentNode.lastChild)
	{
		replaceNodeWithChildren(selectionStart.parentNode);
	}

	var startParent = selectionStart.parentNode;

	var parentInline = getCommonParent(selectionStart, selectionEnd);

	/* If selection is inside an inline element, remove only the selected part */
	while (parentInline != null && !parentInline.nodeName.isBlockName())
	{
		if (parentInline.parentNode != null && parentInline.nodeName.toLowerCase() == elementName)
		{
			var startParentClone = parentInline.cloneNode(true);
			var nextElement = getNextElement(startParentClone);

			while (nextElement.id != "selectionStart")
			{
				nextElement = getNextElement(nextElement);
			}

			while (nextElement != null)
			{
				var currElement = nextElement;
				nextElement = getNextElement(nextElement);
				currElement.parentNode.removeChild(currElement);
			}

			var endParentClone = parentInline.cloneNode(true);
			var endParentCloneSelectionEnd = getNextElement(endParentClone);

			while (endParentCloneSelectionEnd.id != "selectionEnd")
			{
				endParentCloneSelectionEnd = getNextElement(endParentCloneSelectionEnd);
			}

			var nextElement = getNextElement(endParentClone);

			while (nextElement.id != "selectionEnd")
			{
				if (nextElement.nodeType == 3 || !isDescendantNode(endParentCloneSelectionEnd, nextElement))
				{
					var currElement = nextElement;
					nextElement = getNextHigherElement(nextElement);
					currElement.parentNode.removeChild(currElement);
				}
				else
				{
					nextElement = getNextElement(nextElement);
				}
			}

			nextElement.parentNode.removeChild(nextElement);

			parentInline.parentNode.insertBefore(startParentClone, parentInline);
			Ext.get(endParentClone).insertAfter(parentInline);

			var nextElement = getNextElement(parentInline);

			while (nextElement.id != "selectionStart")
			{
				if (nextElement.nodeType == 3 || !isDescendantNode(selectionStart, nextElement))
				{
					var currElement = nextElement;
					nextElement = getNextHigherElement(nextElement);
					currElement.parentNode.removeChild(currElement);
				}
				else
				{
					nextElement = getNextElement(nextElement);
				}
			}

			var nextElement = getNextHigherElement(selectionEnd);

			while (isDescendantNode(nextElement, parentInline))
			{
				var currElement = nextElement;
				nextElement = getNextHigherElement(nextElement);
				currElement.parentNode.removeChild(currElement);
			}

			replaceNodeWithChildren(parentInline);


			break;
		}

		parentInline = parentInline.parentNode;
	}

	removeEmpties(getCommonParent(selectionStart, selectionEnd));

	selectSelectionBoundaries(editor.iframeWindow);
	deleteSelectionBoundaries(editor.iframeWindow);
	
	return true;
};




/* Clean the HTML code of the content area */
cleanSource = function(html, preserveSelection)
{
	html = html.validateTags();

	/* Remove leading and trailing whitespace */
	html = html.replace(/^\s+/, "");
	html = html.replace(/\s+$/, "");
	/* Remove style attribute inside any tag */
//	html = html.replace(/ style="[^"]*"/g, "");
	/* Replace improper BRs */
	html = html.replace(/<br>/g, "<br />");
	/* Replace improper HRs */
	html = html.replace(/<hr>/g, "<hr />");
	/* Replace improper IMGs */
	html = html.replace(/(<img [^>]+[^\/])>/g, "$1 />");
	/* Replace opening bold tags with strong */
	html = html.replace(/<b(\s+|>)/g, "<strong$1");
	/* Replace closing bold tags with closing strong */
	html = html.replace(/<\/b(\s+|>)/g, "</strong$1");
	/* Replace opening italic tags with em */
	html = html.replace(/<i(\s+|>)/g, "<em$1");
	/* Replace closing italic tags with closing em */
	html = html.replace(/<\/i(\s+|>)/g, "</em$1");
	/* Remove BRs right before the end of blocks */
	html = html.replace(/<br \/>\s*<\/(h1|h2|h3|h4|h5|h6|li|p)/g, "</$1");
	/* Remove &nbsp; at the start of blocks */
	html = html.replace(/<(h1|h2|h3|h4|h5|h6|li|p)([^>]*)>\s*(&nbsp;|\xA0)([^<])/g, "<$1$2>$4");
	/* Remove &nbsp; right before the end of blocks */
	html = html.replace(/([^>])(&nbsp;|\xA0|\s)*<\/(h1|h2|h3|h4|h5|h6|li|p)/g, "$1</$3");
	if (preserveSelection)
	{
		/* Preserve empty var tags (for selection) */
		html = html.replace(/(<var[^>]*>)\s*<\/var>/g, "$1-</var>");
	}
	/* Remove empty tags */
	html = html.replace(/(<[^\/]>|<[^\/][^>]*[^\/]>)\s*<\/[^>]*>/g, "");
	/* Remove contents of var tags (for selection) */
	html = html.replace(/(<var[^>]*>)[^<]*<\/var>/g, "$1</var>");
	/* Remove Ext-generated IDs */
	html = html.replace(/ id="ext-gen[^"]+"/g, "");
	/* Final cleanout for MS Word cruft */
	html = html.replace(/<\?xml[^>]*>/g, "");
	html = html.replace(/<[^ >]+:[^>]*>/g, "");
	html = html.replace(/<\/[^ >]+:[^>]*>/g, "");
	return html;
};




/* Determine whether one element is a child of another */
function isDescendantNode(descendant, ancestor)
{
	while (descendant.parentNode != null && descendant.parentNode.nodeName.toLowerCase() != "#document")
	{
		if (descendant.parentNode == ancestor)
		{
			return true;
		}
		else
		{
			descendant = descendant.parentNode;
		}
	}
	
	return false;
};




/* Replace a node with its children -- delete the item and move its children up one level in the hierarchy */
function replaceNodeWithChildren(theNode)
{
	var theChildren = new Array();
	var theParent = theNode.parentNode;
	var theIndex = 0;
	
	if (theParent != null)
	{
		/* Find the index of the element to be removed, as its first child will now take its place, and we can return this from the function */
		for (var i = 0; i < theParent.childNodes.length; i++)
		{
			if (theParent.childNodes[i] == theNode)
			{
				theIndex = i;

				break;
			}
		}
	
		for (var i = 0; i < theNode.childNodes.length; i++)
		{
			theChildren.push(theNode.childNodes[i].cloneNode(true));
		}
		
		for (var i = 0; i < theChildren.length; i++)
		{
			theParent.insertBefore(theChildren[i], theNode);
		}
		
		theParent.removeChild(theNode);
		
		return theParent.childNodes[theIndex];
	}
	
	return null;
};




/* Remove empty elements */
function removeEmpties(parentElement)
{
	/* Clean-up empty elements */
	var nextElement = getNextElement(parentElement);

	while (nextElement != null && isDescendantNode(nextElement, parentElement))
	{
		if (isEmptyElement(nextElement))
		{
			currElement = nextElement;
			nextElement = getNextHigherElement(nextElement);
			currElement.parentNode.removeChild(currElement);
		}
		else
		{
			nextElement = getNextElement(nextElement);
		}
	}

	return true;
};




/* Retrieve a cross-browser selection object */
function selectionObj(windowRef)
{
	this.selection = null;
	this.collapsed = false;
	this.textRange = null;

	try
	{
		/* Mozilla/Safari selection handling */	
		if (typeof windowRef.getSelection == "function")
		{
			this.selection = windowRef.getSelection();

			/* Mozilla text range handling */
			if (typeof this.selection.getRangeAt == "function" && this.selection.rangeCount > 0)
			{
				this.textRange = this.selection.getRangeAt(0);
			}

			/* Safari text range handling */
			else if (typeof this.selection.baseNode != "undefined")
			{
				/* Create a range from the end nodes to see whether the baseNode is after the extentNode i.e. the selection is from right to left */
				this.textRange = windowRef.document.createRange();

				this.textRange.setStart(this.selection.baseNode, this.selection.baseOffset);
				this.textRange.setEnd(this.selection.extentNode, this.selection.extentOffset);

				if (this.textRange.collapsed)
				{
					this.textRange.setEnd(this.selection.baseNode, this.selection.baseOffset);
					this.textRange.setStart(this.selection.extentNode, this.selection.extentOffset);
				}
			}
			else
			{
				return false;
			}

			if (this.selection.isCollapsed)
			{
				this.collapsed = true;
			}
		}

		/* Internet Explorer selection handling */
		else if (typeof windowRef.document.selection != "undefined")
		{
			this.selection = windowRef.document.selection;
			this.textRange = this.selection.createRange();

			if (this.selection.type == "None")
			{
				this.collapsed = true;
			}
		}
		else
		{
			return null;
		}

		return true;
	}
	catch (error)
	{
		return false;
	}
};




/* Check if a string is the nodeName of an accepted element */
String.prototype.isAcceptedElementName = function()
{
	var elementList = new Array("#text", "a", "blockquote", "br", "del", "em", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "img", "li", "ol", "p", "strong", "u", "ul", "var");
	var theName = this.toLowerCase();
	
	for (var i = 0; i < elementList.length; i++)
	{
		if (theName == elementList[i])
		{
			return true;
		}
	}
	
	return false;
};




/* Check if a string is the nodeName of a block element */
String.prototype.isBlockName = function()
{
	var blockList = new Array("body", "blockquote", "div", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "li", "ol", "p", "ul");
	var theName = this.toLowerCase();
	
	for (var i = 0; i < blockList.length; i++)
	{
		if (theName == blockList[i])
		{
			return true;
		}
	}
	
	return false;
};




/* Check if a string is the nodeName of an inline element */
String.prototype.isInlineName = function()
{
	var inlineList = new Array("#text", "a", "br", "del", "em", "font", "span", "strong", "u", "var");
	var theName = this.toLowerCase();
	
	for (var i = 0; i < inlineList.length; i++)
	{
		if (theName == inlineList[i])
		{
			return true;
		}
	}
	
	return false;
};




/* Check if a string is the nodeName of an element that is not allowed to have any children */
String.prototype.isValidEmpty = function()
{
	var emptyList = new Array("br", "hr", "img");
	var theName = this.toLowerCase();
	
	for (var i = 0; i < emptyList.length; i++)
	{
		if (theName == emptyList[i])
		{
			return true;
		}
	}
	
	return false;
};




/* Make tags valid by converting uppercase element and attribute names to lowercase and quoting attributes */
String.prototype.validateTags = function()
{
	var theString = this;
	
	/* Replace uppercase element names with lowercase */
	theString = theString.replace(/<[^> ]*/g, function(match){return match.toLowerCase();});
	
	/* Replace uppercase attribute names with lowercase */
	theString = theString.replace(/<[^>]*>/g, function(match)
		{
			match = match.replace(/ [^= "]+=/g, function(match2){return match2.toLowerCase();});

			return match;
		});
			
	/* Put quotes around unquoted attributes */
	theString = theString.replace(/<[^>]*>/g, function(match)
		{
			match = match.replace(/( [^=]+=)([^"][^ >]*)/g, "$1\"$2\"");
			
			return match;
		});
		
	/* Remove empty attributes */
	theString = theString.replace(/<[^>]*>/g, function(match)
		{
			match = match.replace(/ [^=]+=""/g, "");
			
			return match;
		});
		
	return theString;
};




function createElement(windowRef, elementName, attributes)
{
	var element = windowRef.document.createElement(elementName);
	
	if (typeof attributes != "undefined")
	{
		for (var att in attributes)
		{
			element.setAttribute(att, attributes[att]);
		}
	}
	
	return element;
};




function getPosition(theElement)
{
  var positionX = 0;
  var positionY = 0;

  while (theElement != null)
  {
    positionX += theElement.offsetLeft;
    positionY += theElement.offsetTop;
    theElement = theElement.offsetParent;
  }
  
  return [positionX, positionY];
};

var widgConfig = {

	/* Path to toolbar images */
	imagePath: "images/",

	/* Path to plugins */
	pluginsPath: "plugins/",

	/* Path to stylesheet for content inside editor */
	widgStylesheet: "css/widgContent.css",
	
	/* Automatically clean pasted content */
	autoClean: true,
	
	/* Swap shit-enter and ctrl-enter for line breaks and submission */
	shiftSubmit: false
	
};




var widgButtons = {
	/* Default button types */
	bold: {
		className: "widgButtonBold",
		title: "Bold",
		action: onclickBold,
		image: widgConfig.imagePath + "widgeditor_button_bold.gif"
	},
	
	italic: {
		className: "widgButtonItalic",
		title: "Italic",
		action: onclickItalic,
		image: widgConfig.imagePath + "widgeditor_button_italic.gif"
	},
	
	strikethrough: {
		className: "widgButtonStrikethrough",
		title: "Strikethrough",
		action: onclickStrikethrough,
		image: widgConfig.imagePath + "widgeditor_button_strikethrough.gif"
	},
	
	underline: {
		className: "widgButtonUnderline",
		title: "Underline",
		action: onclickUnderline,
		image: widgConfig.imagePath + "widgeditor_button_underline.gif"
	},
	
	unordered: {
		className: "widgButtonUnordered",
		title: "Unordered List",
		action: onclickUnorderedList,
		image: widgConfig.imagePath + "widgeditor_button_unordered.gif"
	},
	
	ordered: {
		className: "widgButtonOrdered",
		title: "Ordered List",
		action: onclickOrderedList,
		image: widgConfig.imagePath + "widgeditor_button_ordered.gif"
	}
};




/* Buttons to be included on toolbar. Consists of (class name, title/alt, event handler, image) */
widgConfig.toolbarButtons = [widgButtons.bold, widgButtons.italic, widgButtons.underline, widgButtons.strikethrough, "colour", "anchor", "emoticons", widgButtons.unordered, widgButtons.ordered, "image", "video"];
