/**
* 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 = 'base';
    this.baseSmiles = new Array(new Array('smile.gif', 'Smile', ':)'),new Array('laugh.gif', 'Laugh', ':D'),new Array('frown.gif', 'Frown', ':('),new Array('wink.gif', 'Wink', ';)'),new Array('blush.gif', 'Blush', ':blush:'),new Array('eek.gif', 'Eek', ':eek:'),new Array('pardon.gif', 'Pardon', ':pardon:'),new Array('cry.gif', 'Cry', ':cry:'),new Array('cool.gif', 'Cool', ':cool:'),new Array('angry.gif', 'Angry', ':angry:'),new Array('finger_up.gif', 'Thumbs up', ':finger_up:'),new Array('finger_down.gif', 'Thumbs down', ':finger_down:'),new Array('rose.gif', 'Rose', ':rose:'));
    this.allSmiles = new Array();
    this.allSmilesTitles = {'':''};
    this.smilesCopyright = '';

    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(/<.*?>/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(){
        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>');
        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;
            return '<PRE class="edCode" style="height:'+(nlCount*fontHeight+40)+'">'+tagContent+'</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)+'">'});
        taValue = taValue.replace(/\[(COLOR|SIZE)=&quot;(.*?)&quot;\]/gi, function(allstr, tagParam, paramValue){return '<FONT '+tagParam+'="'+_tagsParamReplace(paramValue)+'">'});
        taValue = taValue.replace(/\[\/(FONT|SIZE|COLOR)\]/gi, '</FONT>');

        taValue = taValue.replace(/\[URL=&quot;(.*?)&quot;\]((?:.|\r|\n)*?)\[\/URL\]/gi, function(allstr, url, linkContent){
            var curUseNoIndex = localUseNoIndex;
            var curUrl = _tagsParamReplace(url);
            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">'+linkContent+'</A>'+(curUseNoIndex ? '</NOINDEX>' : '');
        });

        var allSmilesTitles = this.allSmilesTitles;
        taValue = taValue.replace(/\[IMG\](.*?)\[\/IMG\]/gi, function(allstr, url){return '<IMG SRC="'+_tagsParamReplace(url)+'">'});
        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;
        });

        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, tagUrl, tagContent){var tagUrl = tagUrl.replace(/^('|")(.*?)\1$/g, '$2'); return textStart+'[URL="'+tagUrl+'"]'+tagContent+'[/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){
        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+'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="OFF" 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){
        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();
            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){
    return param.replace(/&amp;/, '&');
}