/**
* Amiro.CMS text editor
*
* Textarea editor with pseudo codes and preview support
* @version 1.0. Last changes: 31/08/2007
* @copyright Amiro.CMS. All rights reserved. Changes are not allowed.
*/
function amiroTEdit(varName, langData){
    this.isInitialized = false;
    this.currentMode = 'editor';
    this.varName = varName;
    this.editorId = '';
    this.idPreviewDiv = 'amiroTEdDivPreview';
    this.previewButtonObj = undefined;
    this.editorObj = false;
    this.langData = (langData == undefined ? Array() : langData);
    this.isIE = true;
    this.useNoIndex = false;
    this.fontHeight = 15;
    this.regTextAreaResizeY = 0;
    this.editorModeCode = false;
    this.updatePreviewMode = '';
    this.allowedImages = new Array ();
    this.aTags = {
        'empty' : Array('', ''),
        'bold' : Array('[B]', '[/B]'),
        'indent' : Array('[INDENT]', '[/INDENT]'),
        'code' : Array('[CODE]', '[/CODE]'),
        'italic' : Array('[I]', '[/I]'),
        'underlined' : Array('[U]', '[/U]'),
        'quote' : Array('[Q]', '[Q="#\#value#\#"]', '[/Q]'),
        'align:left' : Array('[LEFT]', '[/LEFT]'),
        'align:right' : Array('[RIGHT]', '[/RIGHT]'),
        'align:center' : Array('[CENTER]', '[/CENTER]'),
        'align:justify' : Array('[JUSTIFY]', '[/JUSTIFY]'),
        'ulist' : Array('[LIST]', '\n[/LIST]'),
        'ulist_item' : Array('\n[*]', ''),
        'addlink' : Array('[URL="#\#value#\#"]', '[/URL]'),
        'addimg' : Array('[IMG]', '[/IMG]'),
        'font_family' : Array('[FONT="#\#value#\#"]', '[/FONT]'),
        'font_size' : Array('[SIZE="#\#value#\#"]', '[/SIZE]'),
        'font_color' : Array('[COLOR="#\#value#\#"]', '[/COLOR]'),
        'smile' : Array('', '')
    };
    this.usedFonts = new Array('Times New Roman','Georgia','Arial','Arial Black','Arial Narrow','Book Antiqua','Comic Sans MS','Courier New','Lucida Concole','Tahoma','Verdana');
    this.maxTextSize = 7;
    this.usedColors = new Array('Black','Sienna','DarkOliveGreen','DarkGreen','DarkSlateBlue','Navy','Indigo','DarkSlateGray','DarkRed','DarkOrange','Olive','Green','Teal','Blue','SlateGray','DimGray','Red','SandyBrown','YellowGreen','SeaGreen','MediumTurquoise','RoyalBlue','Purple','Gray','Magenta','Orange','Yellow','Lime','Cyan','DeepSkyBlue','DarkOrchid','Silver','Pink','Wheat','LemonChiffon','PaleGreen','PaleTurquoise','LightBlue','Plum','White');
    this.smilesPath = 'aiwanlight';
    this.baseSmiles = new Array(new Array('wink.gif', 'Wink', ';)'),new Array('smile.gif', 'Smile', ':)'),new Array('laugh.gif', 'Laugh', ':D'),new Array('yahoo.gif', 'Yahoo', ':yahoo:'),new Array('yes.gif', 'Yes', ':yes:'),new Array('no.gif', 'No', ':no:'),new Array('blush.gif', 'Blush', ':blush:'),new Array('frown.gif', 'Frown', ':('),new Array('wall.gif', 'Wall', ':wall:'),new Array('cry.gif', 'Cry', ':cry:'));
    this.allSmiles = new Array(new Array('aggressive.gif', 'Aggressive', ':aggressive:'),new Array('bad.gif', 'Bad', ':bad:'),new Array('beee.gif', 'Beee', ':beee:'),new Array('blum.gif', 'Blum', ':blum:'),new Array('blush.gif', 'Blush', ':blush:'),new Array('clapping.gif', 'Clapping', ':clapping:'),new Array('crazy.gif', 'Crazy', ':crazy:'),new Array('cry.gif', 'Cry', ':cry:'),new Array('diablo.gif', 'Diablo', ':diablo:'),new Array('dirol.gif', 'Dirol', ':dirol:'),new Array('dontmention.gif', 'Don\'t mention', ':dontmention:'),new Array('drinks.gif', 'Drinks', ':drinks:'),new Array('fool.gif', 'Fool', ':fool:'),new Array('friends.gif', 'Friends', ':friends:'),new Array('frown.gif', 'Frown', ':('),new Array('girl_hospital.gif', 'Girl hospital', ':girl_hospital:'),new Array('give_heart.gif', 'Give heart', ':give_heart:'),new Array('give_rose.gif', 'Give rose', ':give_rose:'),new Array('good.gif', 'Good', ':good:'),new Array('goodx.gif', 'Good', ':goodx:'),new Array('help.gif', 'Help', ':help:'),new Array('ireful.gif', 'Ireful', ':ireful:'),new Array('kiss.gif', 'Kiss', ':kiss:'),new Array('laugh.gif', 'Laugh', ':D'),new Array('mosking.gif', 'Mosking', ':mosking:'),new Array('negative.gif', 'Negative', ':negative:'),new Array('no.gif', 'No', ':no:'),new Array('offtopic.gif', 'Offtopic', ':offtopic:'),new Array('ok.gif', 'Ok', ':ok:'),new Array('pardon.gif', 'Pardon', ':pardon:'),new Array('pleasantry.gif', 'Pleasantry', ':pleasantry:'),new Array('resent.gif', 'Resent', ':resent:'),new Array('rofl.gif', 'Rofl', ':rofl:'),new Array('sad.gif', 'Sad', ':sad:'),new Array('secret.gif', 'Secret', ':secret:'),new Array('shok.gif', 'Shok', ':shok:'),new Array('smile.gif', 'Smile', ':)'),new Array('sorry.gif', 'Sorry', ':sorry:'),new Array('stop.gif', 'Stop', ':stop:'),new Array('suicide.gif', 'Suicide', ':suicide:'),new Array('superstition.gif', 'Superstition', ':superstition:'),new Array('tease.gif', 'Tease', ':tease:'),new Array('thank_you.gif', 'Thank you', ':thank_you:'),new Array('this.gif', 'This', ':this:'),new Array('umnik.gif', 'Umnik', ':umnik:'),new Array('unknw.gif', 'Unknow', ':unknw:'),new Array('victory.gif', 'Victory', ':victory:'),new Array('wacko.gif', 'Wacko', ':wacko:'),new Array('wall.gif', 'Wall', ':wall:'),new Array('wink.gif', 'Wink', ';)'),new Array('yahoo.gif', 'Yahoo', ':yahoo:'),new Array('yes.gif', 'Yes', ':yes:'));
    this.allSmilesTitles = {'':''};
    this.smilesCopyright = 'Автор смайлов: <noindex><a href=\'http://www.kolobok.us/\' rel=\'nofollow\' target=\'_blank\'>Aiwan</a></noindex>';

    this.init = function(){
        userAgent = navigator.userAgent.toLowerCase();
        this.isIE = userAgent.indexOf('msie') != -1 && userAgent.indexOf('opera') == -1 && typeof(window.opera) == 'undefined';
        if(typeof(this.langData) != 'object' || this.langData.length == 0){
            this.langData = new Array(
                'Bold',
                'Italic',
                'Underline',
                'Quote',
                'Align left',
                'Align center',
                'Align right',
                'Justify',
                'Insert list',
                'Insert link',
                'Delete link',
                'Insert image',
                'Font',
                'Size',
                'Color',
                'more',
                'Insert code',
                'Indent',
                'Outdent',
                'Preview',
                'Hide preview',
                'Update preview',
                'Message to short!'
            );
        }
        for(i = 0; i < this.baseSmiles.length; i++){
            this.allSmilesTitles[this.baseSmiles[i][0]] = this.baseSmiles[i][1];
        }
        for(i = 0; i < this.allSmiles.length; i++){
            this.allSmilesTitles[this.allSmiles[i][0]] = this.allSmiles[i][1];
        }
    }

    this.setUseNoindex = function(noindexState){
        this.useNoIndex = noindexState;
    }

    this.setFontHeight = function(fontHeight){
        this.fontHeight = fontHeight;
    }

    this.procAction = function(action, subaction){
        var res = false;
        if(this.isInitialized){
            if(this._procAction(action, subaction)){
                res = true;
            }
        }
        return res;
    }

    this._procAction = function(action, subaction){
        var success = false;
        switch(action){
            case 'bold':
            case 'italic':
            case 'underlined':
            case 'code':
            case 'indent':
                this._boundSelectionWithTags(this.aTags[action]);
                success = true;
                break;
            case 'outdent':
                var selTxt = this._getSelectedText();
                if(selTxt != '' && selTxt.indexOf('[INDENT]') != -1 && selTxt.indexOf('[/INDENT]') != -1){
                    selTxt = selTxt.replace(/\[INDENT\]((.|\r|\n)*?)\[\/INDENT\]/g, '$1');
                    this._boundSelectionWithTags(this.aTags['empty'], selTxt);
                    success = true;
                }
                break;
            case 'quote':
                if(typeof(subaction) == "undefined"){
                    subaction = "";
                }
                var selTxt = this._getSelectedText();
                var tmpTags = new Array(subaction.length == 0 ? this.aTags['quote'][0] : this.aTags['quote'][1], this.aTags['quote'][2]);
                subaction = subaction.replace(/<[a-zA-Z\/].*?>/g, '');
                selTxt = selTxt.replace(/<[a-zA-Z\/].*?>/g, '');
                tmpTags[0] = tmpTags[0].replace(/#\#value#\#/g, subaction.replace(/"/g, '&quot;'));
                this._boundSelectionWithTags(tmpTags, selTxt);
                success = true;
                break;
            case 'align':
                if(subaction != undefined && this.aTags['align:'+subaction]){
                    this._boundSelectionWithTags(this.aTags['align:'+subaction]);
                    success = true;
                }
                break;
            case 'ulist':
                var selTxt = this._getSelectedText();
                if(selTxt != ''){
                    this._procSelectionList(selTxt);
                }else{
                    this._boundSelectionWithTags(this.aTags['ulist']);
                    var listLine = '';
                    listLine = prompt('Введите элемент списка', '');
                    while(listLine != '' && listLine != null){
                        this._boundSelectionWithTags(this.aTags['ulist_item'], listLine, true);
                        listLine = prompt('Введите элемент списка. Пустота для завершения списка.', '');
                    }
                }
                success = true;
                break;
            case 'addlink':
                urlLine = prompt('Введите URL', 'http://');
                if(urlLine != '' && urlLine != null){
                    var selTxt = this._getSelectedText();
                    var tmpTags = new Array(this.aTags['addlink'][0], this.aTags['addlink'][1]);
                    tmpTags[0] = tmpTags[0].replace(/#\#value#\#/g, urlLine.replace(/"/g, '&quot;'));
                    selTxt = selTxt == '' ? urlLine : selTxt;
                    this._boundSelectionWithTags(tmpTags, selTxt);
                    success = true;
                }
                break;
            case 'dellink':
                var selTxt = this._getSelectedText();
                if(selTxt != '' && selTxt.indexOf('[URL') != -1 && selTxt.indexOf('[/URL]') != -1){
                    selTxt = selTxt.replace(/\[URL=\".*?\"\]/g, '');
                    selTxt = selTxt.replace(/\[\/URL\]/g, '');
                    this._boundSelectionWithTags(this.aTags['empty'], selTxt);
                    success = true;
                }
                break;
            case 'addimg':
                var urlLine = 'http://';
                do {
                    urlLine = prompt('Введите URL изображения', urlLine);
                    askURL = urlLine != null;
                    if (askURL) {
                        urlLine = urlLine.replace(/^(.*?)\?.*$/, '$1');
                        if (urlLine != '') {
                            var allowedImages = this.allowedImages;
                            var re = /^https?\:\/\/([^\/]+)(\/[^\?]*)(\?.*)?/;
                            re.exec(urlLine);
                            if (RegExp.$2 == '' || RegExp.$1 == '') {
                                alert(this.langData[23]);
                            } else if (allowedImages.indexOf('internal_links') < 0 && urlLine.indexOf(frontBaseHref) == 0) {
                                alert(this.langData[24]);
                            } else if (allowedImages.indexOf('external_links') < 0 && urlLine.indexOf(frontBaseHref) != 0) {
                                alert(this.langData[25]);
                            } else {
                                var tmpTags = new Array(this.aTags['addimg'][0], this.aTags['addimg'][1]);
                                this._boundSelectionWithTags(tmpTags, urlLine);
                                success = true;
                                askURL = false;
                            }
                        }
                    }
                } while (askURL);
                break;
            case 'font_family':
            case 'font_size':
            case 'font_color':
                if(subaction != undefined && subaction != ''){
                    var tmpTags = new Array(this.aTags[action][0], this.aTags[action][1]);
                    tmpTags[0] = tmpTags[0].replace(/#\#value#\#/g, subaction);
                    this._boundSelectionWithTags(tmpTags);
                    success = true;
                }
                break;
            case 'smile':
                if(subaction != undefined){
                    this._boundSelectionWithTags(this.aTags['smile'], subaction, true);
                    success = true;
                }
                break;
        }
        this.updatePreviewButton();
        return success;
    }

    this._boundSelectionWithTags = function(pTags, text, setPointerToEnd){
        if(pTags[0] == undefined)
            pTags[0] = '';
        if(pTags[1] == undefined)
            pTags[1] = '';
        if(text == undefined)
            text = this._getSelectedText();
        this._replaceSelection(pTags[0]+text+pTags[1], pTags[0].length, pTags[1].length, setPointerToEnd);
    }

    this._procSelectionList = function(text){
        // Try to understand next regexp ;-). From start of string any not empty string which does not start from [/?LIST] or [*]
        text = text.replace(/(^|\n)(?!(\r?\n)|(\[\/?LIST\])|(\[\*\]))/g, this.aTags['ulist_item'][0]);
        this._boundSelectionWithTags(this.aTags['ulist'], text);
    }

    this._calcMultiLineTextLen = function(text){
        if(this.isIE){
            text = text.replace(/\r/g, '');
        }
        return text.length;
    }

    this._getSelectedText = function(){
        var text = '';
        this.editorObj.focus();
        if(document.selection && document.selection.createRange()){
            var sRange = document.selection.createRange();
            text = sRange.text;
        }else if(typeof(this.editorObj.selectionStart) != undefined){
            var sStart = parseInt(this.editorObj.selectionStart);
            var sEnd = parseInt(this.editorObj.selectionEnd);
            text = this.editorObj.value;
            text = text.substr(sStart, sEnd-sStart);
        }
        return text;
    }

    this._replaceSelection = function(newText, newSelDl, newSelDr, setPointerToEnd){
        this.editorObj.focus();

        if(document.selection && document.selection.createRange()){
            var sRange = document.selection.createRange();
            sRange.text = newText.replace(/\r?\n/g, '\r\n');
            if(setPointerToEnd)
                sRange.moveStart('character', -newSelDr);
            else
                sRange.moveStart('character', -this._calcMultiLineTextLen(newText)+newSelDl);
            sRange.moveEnd('character', -newSelDr);
            sRange.select();

        }else if(typeof(this.editorObj.selectionStart) != undefined){
            var sStart = parseInt(this.editorObj.selectionStart);
            var sEnd = parseInt(this.editorObj.selectionEnd);
            var sTop = this.editorObj.scrollTop;
            var sText = this.editorObj.value;
            this.editorObj.value = sText.substr(0, sStart)+newText+sText.substr(sEnd);
            if(setPointerToEnd)
                this.editorObj.selectionStart = sStart+newText.length-newSelDr;
            else
                this.editorObj.selectionStart = sStart+newSelDl;
            this.editorObj.selectionEnd = sStart+newText.length-newSelDr;
            this.editorObj.scrollTop = sTop;
        }
    }

    this.regTextAreaResize = function(clientY){
        this.regTextAreaResizeY = clientY;
        globalATEObj = this;
        document.onmousemove = handleMouseMove;
        document.onmouseup = releaseMouseMoveHandler;
        return false;
    }

    this.handleMouseMove = function(clientY){
        if(this.regTextAreaResizeY > 0){
            var reqHeight = this.editorObj.offsetHeight-this.regTextAreaResizeY+clientY;
            if(reqHeight > 50){
                this.editorObj.style.height = reqHeight;
                this.regTextAreaResizeY = clientY;
            }
        }
        return false;
    }

    this._HTMLSpecialChars = function(taValue){
        taValue = taValue.replace(/&/g, '&amp;');
        taValue = taValue.replace(/"/g, '&quot;');
        taValue = taValue.replace(/</g, '&lt;');
        taValue = taValue.replace(/>/g, '&gt;');
        return taValue;
    }


    this.getHTMLContent = function(cutLongURL){
        var baseHref = typeof(frontBaseHref) == 'string' ? frontBaseHref : (typeof(editorBaseHref) == 'undefined' ? '' : editorBaseHref);
        var smilesPath = baseHref + '_mod_files/smiles/' + this.smilesPath + '/';
        var specSmiles = {";)":"wink", ":)":"smile", ":D":"laugh", ":(":"frown"};
        var localUseNoIndex = this.useNoIndex;
        var fontHeight = this.fontHeight;

        taValue = this._HTMLSpecialChars(this.editorObj.value);
        taValue = taValue.replace(/\r?\n/g, '<br>\r\n');
        taValue = taValue.replace(/\[(\/?)(B|I|U)\]/gi, '<$1$2>');
        window.amiSimpleEditorCodes = new Array();
        taValue = taValue.replace(/\[CODE\]((?:.|\r|\n)*?)\[\/CODE\]/gi,  function(allstr, tagContent){
            tagContent = tagContent.replace(/<br>/gi, '');
            var nlCount = 1;
            var nlPos = tagContent.indexOf('\n');
            while(nlPos != -1){
                nlCount++;
                nlPos = tagContent.indexOf('\n', nlPos+1);
            }
            if(nlCount > 10)
                nlCount = 10;
            var codeKey = window.amiSimpleEditorCodes.length;
            window.amiSimpleEditorCodes[codeKey] = tagContent;
            return '<PRE class="edCode" style="height:'+(nlCount*fontHeight+40)+'">CodeId_'+codeKey+'</PRE>';
        });
        taValue = taValue.replace(/\[Q\]/gi, '<BLOCKQUOTE class="edQuote">');
        taValue = taValue.replace(/\[Q=&quot;(.*?)&quot;\]/gi, '<BLOCKQUOTE class="edQuote"><b>$1:</b><br>');
        taValue = taValue.replace(/\[(\/?)(INDENT|Q)\]/gi, '<$1BLOCKQUOTE>');
        taValue = taValue.replace(/\[(LEFT|RIGHT|CENTER|JUSTIFY)\]/gi, '<P align="$1">');
        taValue = taValue.replace(/\[\/(LEFT|RIGHT|CENTER|JUSTIFY)\]/gi, '</P>');
        taValue = taValue.replace(/\[LIST\]/gi, '<UL>');
        taValue = taValue.replace(/\[\/LIST\]/gi, '</LI></UL>');
        taValue = taValue.replace(/\[\*\]/gi, '<LI>');
        taValue = taValue.replace(/\[FONT=&quot;(.*?)&quot;\]/gi, function(allstr, fontName){return '<FONT face="'+_tagsParamReplace(fontName, false)+'">'});
        taValue = taValue.replace(/\[(COLOR|SIZE)=&quot;(.*?)&quot;\]/gi, function(allstr, tagParam, paramValue){return '<FONT '+tagParam+'="'+_tagsParamReplace(paramValue, false)+'">'});
        taValue = taValue.replace(/\[\/(FONT|SIZE|COLOR)\]/gi, '</FONT>');

        var urlMaxLength = typeof(cutLongURL) == 'undefined' ? 0 : 50;
        taValue = taValue.replace(/\[URL=&quot;(.*?)&quot;\]((?:.|\r|\n)*?)\[\/URL\]/gi, function(allstr, url, linkContent){
            var curUseNoIndex = localUseNoIndex;
            var curUrl = _tagsParamReplace(url, false);
            if(curUseNoIndex && (!curUrl.match(/^https?:\/\//i) || (baseHref.length > 0 && curUrl.indexOf(baseHref) >= 0)))
                curUseNoIndex = false;
            var attributes = '';
            linkContent = _trim(linkContent);
            var noTagsLinkContent = _trim(_stripTags(linkContent).replace(/\"/g, '&quot;'));
            if ((urlMaxLength > 0) && (noTagsLinkContent.length > urlMaxLength)) {
                attributes =
                    ' title="' + noTagsLinkContent + '"';
                linkContent = noTagsLinkContent.substr(0, urlMaxLength - 8 - 3) + '...' + noTagsLinkContent.substr(noTagsLinkContent.length - 8);
            }
            return (curUseNoIndex ? '<NOINDEX>' : '')+'<A HREF="'+curUrl+'"'+(curUseNoIndex ? ' rel="nofollow"' : '')+' target="_blank"' + attributes + '>'+linkContent+'</A>'+(curUseNoIndex ? '</NOINDEX>' : '');
        });

        var allSmilesTitles = this.allSmilesTitles;
        taValue = taValue.replace(/\[IMG\](.*?)\[\/IMG\]/gi, function(allstr, url){return '<IMG SRC="'+_tagsParamReplace(url, true)+'">'});
        taValue = taValue.replace(/(;\)|:\)|:D|:\()/g, function(allstr, smile){var imgName = specSmiles[smile]+'.gif'; return '<IMG SRC="'+smilesPath+imgName+'" title="'+(typeof(allSmilesTitles[imgName]) != 'undefined' ? allSmilesTitles[imgName] : '')+'">'});
        taValue = taValue.replace(/\:([a-z\_]{1,20})\:/gi, function(allstr, smile){var imgName = smile+'.gif'; return '<IMG SRC="'+smilesPath+smile+'.gif" title="'+(typeof(allSmilesTitles[imgName]) != 'undefined' ? allSmilesTitles[imgName] : '')+'">'});

        taValue = taValue.replace(/((?:<IMG .*?>)|(?:<A (?:.|\r|\n)*?<\/A>))/gi, function(allstr, pTagContent){
            pTagContent = pTagContent.replace(/http(s?)\:/gi, 'htBREAKtp$1:');
            pTagContent = pTagContent.replace(/www/gi, 'wBREAKwBREAKw');
            return pTagContent;
        });
        taValue = taValue.replace(/(https?:\/\/www\.|https?:\/\/|www\.)(?:[a-z0-9\-]+\.)+[a-z]{2,8}[^ \r\n\t'"><]*/gi, function(allstr, prefx){
            var curUseNoIndex = localUseNoIndex;
            var curUrl = _tagsParamReplace(allstr);
            if(prefx.toLowerCase() == 'www.'){
                curUrl = 'http://' + curUrl;
            }
            if(curUseNoIndex && (!curUrl.match(/^https?:\/\//i) || (baseHref.length > 0 && curUrl.indexOf(baseHref) >= 0)))
                curUseNoIndex = false;
            return (curUseNoIndex ? '<NOINDEX>' : '')+'<A HREF="'+curUrl+'"'+(curUseNoIndex ? ' rel="nofollow"' : '')+' target="_blank">'+allstr+'</A>'+(curUseNoIndex ? '</NOINDEX>' : '');
        });
        taValue = taValue.replace(/((?:<IMG .*?>)|(?:<A (?:.|\r|\n)*?<\/A>))/gi, function(allstr, pTagContent){
            pTagContent = pTagContent.replace(/wBREAKwBREAKw/gi, 'www');
            pTagContent = pTagContent.replace(/htBREAKtp(s?):/gi, 'http$1:');
            return pTagContent;
        });
        
        taValue = taValue.replace(/(<PRE[^>]*?>)CodeId_(\d+)(<\/PRE>)/g, function(allstr, preStart, codeId, preEnd){
            var result = preStart;
            if(window.amiSimpleEditorCodes[codeId]){
                result += window.amiSimpleEditorCodes[codeId];
            }
            result += preEnd;
            return result;
        });
        window.amiSimpleEditorCodes = new Array();

        return taValue;
    }

    this.fromHTMLContent = function(taValue){
        var smilesPath = '_mod_files/smiles/' + this.smilesPath + '/';
        var specSmiles = {"wink":";)", "smile":":)", "laugh":":D", "frown":":("};

        // Make single line string
        taValue = taValue.replace(/\r?\n?<br.*?>\r?\n?/gi, '\r\n');
        taValue = taValue.replace(/\\([rn])/gi, '[_spec_rpl_val_$1]');
        taValue = taValue.replace(/\r?\n/g, '\\n');

        // Replace simple elements
        taValue = taValue.replace(/<(\/?)PRE.*?>/gi, '[$1CODE]');
        taValue = taValue.replace(/<(\/?)(B|I|U)(?:>|[^a-z].*?>)/gi, '[$1$2]');
        taValue = taValue.replace(/<(\/?)UL.*?>/gi, '[$1LIST]');
        taValue = taValue.replace(/<LI.*?>/gi, '[*]');
        taValue = taValue.replace(/<\/LI.*?>/gi, '');

        // Replace images and smiles
        taValue = taValue.replace(/<img[^>]*?src=((?:"|').*?(?:"|')|[^\s]*).*?>/gi,
                  function(allstr, tagUrl){
                    var tagUrl = tagUrl.replace(/^('|")(.*?)\1$/g, '$2');
                    var pathPos = tagUrl.indexOf(smilesPath);
                    if(pathPos >= 0){
                        var dotPos = tagUrl.indexOf(".", pathPos+smilesPath.length);
                        if(dotPos >= 0){
                            var startPos = pathPos+smilesPath.length;
                            var smileName = tagUrl.substr(startPos, dotPos-startPos);
                            if(specSmiles[smileName] != undefined){
                                return specSmiles[smileName];
                            }else
                                return ':'+smileName+':';
                        }
                    }
                    return '[IMG]'+tagUrl+'[/IMG]';}
                  );

        // Replace nested elements
        var replaceType = new Array('align', 'font', 'url', 'blockquote');
        for(var i = 0; i < replaceType.length; i++){
            var checkLen = 0;
            do{
                checkLen = taValue.length;
                if(replaceType[i] == 'align')
                    taValue = taValue.replace(/^(.*)<p[^a-z][^>]*?align=(?:"|')?(right|left|center|justify)(?:"|')?.*?>(.*?)<\/p(?:>|[^a-z].*?>)/i, '$1[$2]$3[/$2]');
                else if(replaceType[i] == 'font')
                    taValue = taValue.replace(/^(.*)<font[^>]*?(face|size|color)=((?:"|').*?(?:"|')|[^\s>]*).*?>(.*?)<\/font.*?>/i, function(allstr, textStart, tagName, tagValue, tagContent){var tagTag = (tagName.toLowerCase() == "face" ? "FONT" : tagName.toUpperCase()); tagValue = tagValue.replace(/^('|")(.*?)\1$/g, '$2'); return textStart+'['+tagTag+'="'+tagValue+'"]'+tagContent+'[/'+tagTag+']';});
                else if(replaceType[i] == 'url') {
                    taValue = taValue.replace(/^(.*)<a[^a-z]([^>]*?)href=((?:"|').*?(?:"|')|[^\s>]*)(.*?)>(.*?)<\/a(?:>|[^a-z].*?>)/i,  function(allstr, textStart, tagParams1, tagUrl, tagParams2, tagContent){
                        var tagUrl = tagUrl.replace(/^('|")(.*?)\1$/g, '$2');
                        urlContent = tagContent;
                        if(aParts = (tagParams1 + " " + tagParams2).match(/[^a-z]title="([^"]+)"/i)){
                            urlContent = aParts[1].replace(/&quot;/mg, '"').replace(/&#10;/mg, '\n').replace(/&#13;/mg, '\r');
                        }
                        return textStart + '[URL="' + tagUrl + '"]' + urlContent + '[/URL]';
                    });
                    
                }
                else if(replaceType[i] == 'blockquote'){
                    taValue = taValue.replace(/^(.*)<BLOCKQUOTE(.*?)>(?:\[B\](.*?):\[\/B\]\\n)?(.*?)<\/BLOCKQUOTE>/i, function(allstr, tagBefore, tagInner, qAuthor, tagContent){
                        var isQuote = (tagInner.indexOf('edQuote') >= 0);
                        var hasAuthor = (typeof(qAuthor) != "undefined" && qAuthor.length > 0);
                        if(isQuote){
                            var startTag = '[Q'+(hasAuthor ? '="'+qAuthor+'"' : '')+']';
                            return tagBefore+startTag+tagContent+'[/Q]';
                        }else{
                            return tagBefore+'[INDENT]'+(hasAuthor ? qAuthor : '')+tagContent+'[/INDENT]';
                        }
                    });
                }
            }while(checkLen != taValue.length);
        }

        // Replace HTML base chars
        taValue = taValue.replace(/&lt;/gi, '<');
        taValue = taValue.replace(/&gt;/gi, '>');
        taValue = taValue.replace(/&reg;/gi, '®');
        taValue = taValue.replace(/&copy;/gi, '©');
        taValue = taValue.replace(/&laquo;/gi, '«');
        taValue = taValue.replace(/&raquo;/gi, '»');
        taValue = taValue.replace(/&ndash;/gi, '–');
        taValue = taValue.replace(/&mdash;/gi, '—');
        taValue = taValue.replace(/&euro;/gi, '€');

        // Make multiline string
        taValue = taValue.replace(/\\n/g, '\r\n');
        taValue = taValue.replace(/\[\_spec\_rpl\_val\_([rn])\]/gi, '\\$1');

        return taValue;
    }

    this.createEditor = function(taWidth, taHeight, taValueName, taValue, isValueHTML, idPreviewDiv){
        if (typeof(isValueHTML) != undefined) {
            var re = /(<noindex>|<\/noindex>)/gi;
            taValue = taValue.replace(re, '');
        }
        var baseHref = typeof(frontBaseHref) == 'string' ? '' : (typeof(editorBaseHref) != 'undefined' ? editorBaseHref : '');
        this.editorId = 'id'+taValueName;
        var i = 0;

        var usedFonts = '';
        for(i = 0; i < this.usedFonts.length; i++){
            usedFonts += '<option value="'+this.usedFonts[i]+'">'+this.usedFonts[i]+'</option>';
        }

        var usedSizes = '';
        for(i = 1; i <= this.maxTextSize; i++){
            usedSizes += '<option value="'+i+'">'+i+'</option>';
        }

        var usedColors = '';
        for(i = 0; i < this.usedColors.length; i++){
            usedColors += '<option value="'+this.usedColors[i]+'" style="background-color:'+this.usedColors[i]+'"> </option>';
        }

        var baseSmiles = '';
        for(i = 0; i < this.baseSmiles.length; i++){
            baseSmiles += '<img src="' + baseHref + '_mod_files/smiles/' + this.smilesPath + '/' +this.baseSmiles[i][0]+'" title="'+this.baseSmiles[i][1]+'" onClick="txtEd.procAction(\'smile\', \''+this.baseSmiles[i][2]+'\')" class="amiroTEdSmile">';
        }

        var allSmiles = baseSmiles;
        for(i = 0; i < this.allSmiles.length; i++){
            allSmiles += '<img src="' + baseHref + '_mod_files/smiles/' + this.smilesPath + '/' +this.allSmiles[i][0]+'" title="'+this.allSmiles[i][1]+'" onClick="txtEd.procAction(\'smile\', \''+this.allSmiles[i][2]+'\')" class="amiroTEdSmile">';
        }

        var contentPreviewDiv = '';
        if(typeof(idPreviewDiv) != "undefined"){
            this.idPreviewDiv = idPreviewDiv;
        }else{
            this.idPreviewDiv = 'amiroTEdDivPreview';
            contentPreviewDiv = '<div id="amiroTEdDivPreview" class="amiroTEdDivPreview" style="width:' + (taWidth - 12) + 'px;margin-bottom:7px"></div>';
        }

        var allowedImages = this.allowedImages;
        document.writeln(
            '<div style="width:'+taWidth+'px" id="amiroTEdDiv" class="amiroTEdDiv">' +
            contentPreviewDiv +
            '<div id="amiroTEdPureDiv">' +
            '<nobr>' +
            '<img src="' + baseHref + '_img/ed_bold.gif" title="'+this.langData[0]+'" onClick="txtEd.procAction(\'bold\')" class="amiroTEdCtrl">' +
            '<img src="' + baseHref + '_img/ed_italic.gif" title="'+this.langData[1]+'" onClick="txtEd.procAction(\'italic\')" class="amiroTEdCtrl">' +
            '<img src="' + baseHref + '_img/ed_underline.gif" title="'+this.langData[2]+'" onClick="txtEd.procAction(\'underlined\')" class="amiroTEdCtrl">' +
            '<img src="' + baseHref + '_img/ed_quote.gif" title="'+this.langData[3]+'" onClick="txtEd.procAction(\'quote\')" class="amiroTEdCtrl">' +
            '</nobr>' +
            '<img src="' + baseHref + '_img/ed_sep.gif" class="amiroTEdSep">' +
            '<nobr>' +
            '<img src="' + baseHref + '_img/ed_outdent.gif" title="'+this.langData[18]+'" onClick="txtEd.procAction(\'outdent\')" class="amiroTEdCtrl">' +
            '<img src="' + baseHref + '_img/ed_indent.gif" title="'+this.langData[17]+'" onClick="txtEd.procAction(\'indent\')" class="amiroTEdCtrl">' +
            '</nobr>' +
            '<img src="' + baseHref + '_img/ed_sep.gif" class="amiroTEdSep">' +
            '<nobr>' +
            '<img src="' + baseHref + '_img/ed_alignl.gif" title="'+this.langData[4]+'" onClick="txtEd.procAction(\'align\', \'left\')" class="amiroTEdCtrl">' +
            '<img src="' + baseHref + '_img/ed_alignc.gif" title="'+this.langData[5]+'" onClick="txtEd.procAction(\'align\', \'center\')" class="amiroTEdCtrl">' +
            '<img src="' + baseHref + '_img/ed_alignr.gif" title="'+this.langData[6]+'" onClick="txtEd.procAction(\'align\', \'right\')" class="amiroTEdCtrl">' +
            '<img src="' + baseHref + '_img/ed_alignj.gif" title="'+this.langData[7]+'" onClick="txtEd.procAction(\'align\', \'justify\')" class="amiroTEdCtrl">' +
            '</nobr>' +
            '<img src="' + baseHref + '_img/ed_sep.gif" class="amiroTEdSep">' +
            '<img src="' + baseHref + '_img/ed_list.gif" title="'+this.langData[8]+'" onClick="txtEd.procAction(\'ulist\')" class="amiroTEdCtrl">' +
            '<img src="' + baseHref + '_img/ed_sep.gif" class="amiroTEdSep">' +
            '<nobr>' +
            '<img src="' + baseHref + '_img/ed_link.gif" title="'+this.langData[9]+'" onClick="txtEd.procAction(\'addlink\')" class="amiroTEdCtrl">' +
            '<img src="' + baseHref + '_img/ed_unlink.gif" title="'+this.langData[10]+'" onClick="txtEd.procAction(\'dellink\')" class="amiroTEdCtrl">' +
            (allowedImages.length ? '<img src="' + baseHref + '_img/ed_image.gif" title="'+this.langData[11]+'" onClick="txtEd.procAction(\'addimg\')" class="amiroTEdCtrl">' : '') +
            '<img src="' + baseHref + '_img/ed_code.gif" title="'+this.langData[16]+'" onClick="txtEd.procAction(\'code\')" class="amiroTEdCtrl">' +
            '</nobr>' +
            '<img src="' + baseHref + '_img/ed_sep.gif" class="amiroTEdSep">' +
            '<nobr>' +

            '<select name="amiroTEdit_selfont" onChange="txtEd.procAction(\'font_family\', this.value);this.options[0].selected=true;" class="amiroTEdCtrl">' +
            '<option value="">'+this.langData[12]+'</option>' +
            usedFonts +
            '</select>' +
            '<select name="amiroTEdit_selsize" onChange="txtEd.procAction(\'font_size\', this.value);this.options[0].selected=true;" class="amiroTEdCtrl">' +
            '<option value="">'+this.langData[13]+'</option>' +
            usedSizes +
            '</select>' +
            '<select name="amiroTEdit_selcolor" onChange="txtEd.procAction(\'font_color\', this.value);this.options[0].selected=true;" class="amiroTEdCtrl">' +
            '<option value="">'+this.langData[14]+'</option>' +
            usedColors +
            '</select>' +
            '</nobr>' +
            '<br>' +

            '<div id="amiroTEdDivBaseSmiles">' +
            baseSmiles +
            (allSmiles.length > baseSmiles.length ? '<span onClick="document.getElementById(\'amiroTEdDivAllSmiles\').style.display=\'block\';document.getElementById(\'amiroTEdDivBaseSmiles\').style.display=\'none\'" class="amiroTEdMore">'+this.langData[15]+'</span>' +
            '</div>' +
            '<div id="amiroTEdDivAllSmiles" style="display:none">' +
            allSmiles : '') +
            (this.smilesCopyright != '' ? '<div align="right">'+this.smilesCopyright+'</div>' : '') +
            '</div>' +

            '</div>' +
            '</div>' +

            '<div id="amiroTEdDivEditor" class="amiroTEdDivEditor">' +
            '<textarea id="'+this.editorId+'" name="'+taValueName+'" wrap="fisical" class="amiroTEdCtrl" style="width:'+taWidth+'px;height:'+taHeight+'px" onKeyDown="return '+varName+'.procKeyPress(event)" onKeyUp="'+varName+'.procKeyUp()">' +
            (typeof(isValueHTML) == undefined || !isValueHTML ? taValue : this.fromHTMLContent(taValue)) +
            '</textarea><br>' +
            '<div class="amiroTEdDivResize" style="width:'+taWidth+'px;background-image: url(' + baseHref + '_img/ed_resize.gif)" onMouseDown="'+this.varName+'.regTextAreaResize(event.pageY ? event.pageY : window.event.clientY)"><img src="' + baseHref + '_img/empty.gif" width="1" height="3"></div>' +
            '</div>'

        );
        this.editorObj = document.getElementById(this.editorId);
        this.isInitialized = true;
    }

    this.insertContent = function(taValue, actionType, isValueHTML, subaction, addon){
        if (typeof(isValueHTML) != undefined) {
            var re = /(<noindex>|<\/noindex>)/gi;
            taValue = taValue.replace(re, '');
        }

        this.setMode('editor');
        if(typeof(addon) != "undefined" && actionType == "bold"){
            taValue = "[B]"+taValue+"[/B]"+addon;
            this._replaceSelection(typeof(isValueHTML) == undefined || !isValueHTML ? taValue : this.fromHTMLContent(taValue), 0, 0, true);
        }else{
            this._replaceSelection(typeof(isValueHTML) == undefined || !isValueHTML ? taValue : this.fromHTMLContent(taValue), 0, 0);
            if(actionType != 'undefined' && (actionType == 'quote' || actionType == 'bold' || actionType == 'italic' || actionType == 'underlined')){
                this.procAction(actionType, subaction);
            }
        }
    }

    this.setMode = function(mode){
        if(mode == 'editor' && !this.updatePreviewMode){
            document.getElementById('amiroTEdDivPreview').style.display = 'none';
            this.currentMode = 'editor';
            if(this.editorModeCode.length > 0){
                eval(this.editorModeCode);
            }
        }else if(mode == 'preview' || this.updatePreviewMode){
            var content = this.getHTMLContent(1);
            if (content.length) {
                document.getElementById('amiroTEdDivPreview').style.display = 'block';
                document.getElementById('amiroTEdDivPreview').innerHTML = content;
                this.currentMode = 'preview';
                if (this.updatePreviewMode) {
                    this.previewButtonObj.value = this.langData[20]; // 'Hide preview'
                }
                this.updatePreviewMode = false;
            }
        }
        if (typeof(amiroTEditOnSwitchMode) == 'function') {
            amiroTEditOnSwitchMode(this.currentMode);
        }
    }

    this.switchMode = function(){
        if(this.currentMode == 'editor'){
            this.setMode('preview');
        }else{
            this.setMode('editor');
        }
    }

    this.stopEvent = function(evt){
        if(typeof(evt.stopPropagation) == "function"){
            evt.stopPropagation();
            evt.preventDefault();
            return evt;
        }else{
            window.event.returnValue = false;
            window.event.cancelBubble = true;
            return window.event;
        }
    }

    this.procKeyPress = function(evt){
        if(evt.ctrlKey && evt.keyCode != 17){
            switch(evt.keyCode){
                case 66 /*B*/:
                    this.procAction('bold');
                    return this.stopEvent(evt);
                    break;
                case 73 /*I*/:
                    this.procAction('italic');
                    return this.stopEvent(evt);
                    break;
                case 85 /*U*/:
                    this.procAction('underlined');
                    return this.stopEvent(evt);
                    break;
            }
        }else if(!evt.ctrlKey && !evt.altKey){
            this.updatePreviewButton();
        }
    }

    this.procKeyUp = function()
    {
        if (this.currentMode == 'preview' && this.contentLength() < 2) {
            this.updatePreviewMode = false;
            this.previewButtonOnClick();
            alert(this.langData[22]); // 'Message to short!'
        }
    }

    this.contentLength = function(){
        var contentData = this.editorObj.value;
        contentData = contentData.replace(/[ \t\r\n]/g, '');

        var replaceType = new Array('q');
        for(var i = 0; i < replaceType.length; i++){
            var checkLen = 0;
            do{
                checkLen = contentData.length;
                if(replaceType[i] == 'q'){
                    contentData = contentData.replace(/^(.*)\[Q[^\]]*?\](.*?)\[\/Q\]/i, '$1');
                }
            }while(checkLen != contentData.length);
        }

        contentData = contentData.replace(/\[.*?\]/g, '');
        return contentData.length;
    }

    this.previewButtonOnClick = function(btn)
    {
        if (btn != undefined) {
            this.previewButtonObj = btn;
        } else {
            btn = this.previewButtonObj;
        }
        if (this.currentMode == 'preview') {
            btn.value = this.langData[19]; // 'Preview'
            txtEd.setMode('editor');
        } else if (this.contentLength() < 2) {
            alert(this.langData[22]); // 'Message to short!'
            this.editorObj.focus();
        } else {
            btn.value = this.langData[20]; // 'Hide preview'
            txtEd.setMode('preview');
        }
        return false;
    }

    this.updatePreviewButton = function(){
        if (this.currentMode == 'preview' && this.previewButtonObj != undefined) {
            this.previewButtonObj.value = this.langData[21]; // 'Update preview'
            this.updatePreviewMode = true;
        }
    }

    this.init();
}
function handleMouseMove(evt){
    if(typeof(globalATEObj) == 'object')
        return globalATEObj.handleMouseMove(evt == undefined ? window.event.clientY : evt.pageY);
    else
        return false;
}
function releaseMouseMoveHandler(){
    document.onmousemove = null;
    document.onmouseup = null;
    return false;
}
function _tagsParamReplace(param, doCheckImage){
    var res = param.replace(/&amp;/, '&');
    
    do{
        var prevLength = res.length;
        res = res.replace(/^\s*javascript\:/, '');
    }while(res.length != prevLength);
    
    if(doCheckImage){
        var test = res.replace(/^ *(.*?) *$/i, '$1').toLowerCase();
        if(test.indexOf('/_admin/') >= 0){
            res = '';
        }else{
            var isRelativeAddress = (test.search(/^https?:\/\//) == -1);
            var isLocalAddress = false;
            if(!isRelativeAddress){
                test = test.replace(/^https:\/\//, 'http://');
                var localURL = (frontBaseHref != undefined ? frontBaseHref : (domainName != undefined ? 'http://' + domainName + '/' : ''));
                if(localURL != '' && test.indexOf(localURL) == 0){
                    isLocalAddress = true;
                }
            }
            if((isRelativeAddress || isLocalAddress) && test.search(/^[^?]*\.(jpg|png|gif|jpeg|swf)$/) == -1){
                res = '';
            }
        }
    }
    
    return res;
}

function _stripTags(str)
{
    return str.replace(/<\/?[^\s^>]+[^>]*?>/gi, '');
}

function _trim(str)
{
    return str.replace(/^\s+/mg, '').replace(/\s+$/mg, '');
}
