TT_Editor = Class.create();
TT_Editor.prototype = {
    initialize: function (options) {
        this.id = 'tt';
        this.path = '';
        this.content = '';
        this.isPreview = true;
        this.height = undefined;
        this.tools = undefined;
        this.background = '#F3EBCC';
        this.container = new Element('div', {});
        Object.extend(this, options);
        this.id += '_editor';
        this._tools = {
            forecol:   {command:'forecolor'    , id:'forecol'},
            bgcol:     {command:'hilitecolor'  , id:'bgcol'},
            bold:      {command:'bold'         , id:'bold'},
            italic:    {command:'italic'       , id:'italic'},
            underline: {command:'underline'    , id:'underline'},
            sup:       {command:'superscript'  , id:'sup'},
            sub:       {command:'subscript'    , id:'sub'},
            left:      {command:'justifyleft'  , id:'left'},
            center:    {command:'justifycenter', id:'center'},
            right:     {command:'justifyright' , id:'right'},
            full:      {command:'justifyfull'  , id:'full'},
            indent:    {command:'indent'       , id:'indent'},
            outdent:   {command:'outdent'      , id:'outdent'},
            link:      {command:'createlink'   , id:'link'},
            unlink:    {command:'unlink'       , id:'unlink'},
            image:     {command:'insertimage'  , id:'image'},
            ordlist:   {command:'insertorderedlist'   , id:'ordlist'},
            bullist:   {command:'insertunorderedlist' , id:'bullist'},
            rule:      {command:'inserthorizontalrule', id:'rule'},
            table:     {command:'inserttable'  , id:'table'},
            undo:      {command:'undo'         , id:'undo'},
            redo:      {command:'redo'         , id:'redo'},
            html:      {command:'viewsource'   , id:'html'},
            font:      {}, heading: {}
        };
        this.textFormat = this._textFormat.bindAsEventListener(this);
    },

    getContent: function () {
        if(this.isPreview) 
            return this.doc.body.innerHTML.stripScripts();
        else return $(this.id+'_textarea').value;
    },
    
    setContent: function (textContent) {
        this.doc.body.innerHTML = textContent;
    },

    create: function () {
        this._create();
        var frm = $(this.id);
        this.wnd = frm.contentWindow;
        this.doc = this.wnd.document;
        this.doc.designMode = 'On';
        this.doc.open();
        this.doc.write('<html><head>');
        this.doc.write('<style>');
        this.doc.write('body {');
        this.doc.write('font-size: 11px; ');
        this.doc.write('font-family: Verdana, ');
        this.doc.write('Arial, sans-serif; }');
        this.doc.write('</style>');
        this.doc.write('</head><body>');
        this.doc.write(this.content);
        this.doc.write('</body></html>');
        this.doc.close();
        if (!this.height) {
            this.height = this.doc.body.offsetHeight;
            this.height = this.height>200?this.height: 200;
        }
        frm.style['height'] = this.height + 'px';

    },
    
    _create: function () {
        var htmlString = '';
        htmlString += '<div id="'+this.id+'_source" style="padding: 10px;';
        htmlString +=   'display:none; background: '+this.background+'">';
        htmlString +=   '<div><img id="'+this.id+'_preview" alt="preview" ';
        htmlString +=       'src="'+this.path+'/images/preview.png"></div>';
        htmlString +=   '<textarea id="'+this.id+'_textarea" ';
        htmlString +=       'style="width: 100%;"></textarea>';
        htmlString += '</div>'
        htmlString += '<div id="'+this.id+'_container" ';
        htmlString +=   'style="padding: 10px; margin-bottom: 1px; ';
        htmlString +=   'background: '+this.background+'; ">';
        htmlString +=   '<div id="'+this.id+'_toolbars">';
        htmlString +=   '</div>';
        htmlString +=   '<iframe id="'+this.id+'" border="0" ';
        htmlString +=       'style="background-color: white; ';
        htmlString +=       'color: black; border: none;';
        htmlString +=       'width: 100%; height:'+this.height+'px;"></iframe>';
        htmlString += '</div>';
        if (this.container) this.container.innerHTML = htmlString;
        $(this.id+'_toolbars').appendChild(this._createTools());
        Event.observe(this.id+'_preview', 'click', this.textFormat);
    },
    
    _createTools: function () {
        var toolList = $H(this._tools).keys();
        if (this.tools) toolList = this.tools;
        var divTools = new Element('div', {});
        var divBtns = new Element('div', {});
        for (var i=0; i<toolList.length; i++) {
            if (toolList[i]!='font' && toolList[i]!='heading') {
                var tool = this._tools[toolList[i]];
                var btn = new Element('img', {
                    alt: tool['command'],
                    id : this.id+'_'+tool['id'],
                    src: this.path+'/images/'+tool['id']+'.png',
                    style: 'cursor: pointer'
                });
                divBtns.appendChild(btn);
                Event.observe(btn, 'click', this.textFormat);
            }
        }
        divTools.appendChild(divBtns);
        
        if (toolList.indexOf('font')>=0) {
            var slcStyle = 'margin-bottom: 10px; width: 150px;';
            var slcHeading = new Element('select', {
                id: this.id+'_heading',
                style:  slcStyle, alt: 'formatblock'
            });
            var html = '<option value="<p>">Normal</option>';
            for (var i=1; i<7; i++)
            html += '<option value="<h'+i+'>">Heading '+i+'</option>'
            html += '<option value="<address>">Address</option>';
            slcHeading.innerHTML = html;
            divTools.appendChild(slcHeading);
            Event.observe(slcHeading, 'change', this.textFormat);
        }
        if (toolList.indexOf('heading')>=0) {
            var fontList = [
                {value: '',          content: '- Font -'},
                {value: 'cursive',   content: 'Cursive'},
                {value: 'fantasy',   content: 'Fantasy'},
                {value: 'sans-serif',content: 'Sans Serif'},
                {value: 'serif',     content: 'Serif'},
                {value: 'monospace', content: 'Typewriter'},
            ]; var html = '';
            var slcFont = new Element('select', {
                id: this.id+'_font', 
                style: slcStyle, alt: 'fontname'
            });
            for (var i=0; i<fontList.length; i++) {
                html += '<option value="'+fontList[i]['value']+'">';
                html +=     fontList[i]['content']+'</option>'
            }
            slcFont.innerHTML = html;
            divTools.appendChild(slcFont);
            Event.observe(slcFont, 'change', this.textFormat);
        }
        return divTools;
    },

    _textFormat: function (e) {
        var command = e.target.getAttribute('alt');
        var opt = e.target.value!=undefined?e.target.value:'';
        switch (command) {
            case 'viewsource' : this._viewSource(); break;
            case 'preview'    : this._preview(); break;
            case 'inserttable': this._insertTable(); break;
            case 'insertimage': this._insertImage(); break;
            case 'forecolor'  : this._setColor(e, command); break;
            case 'hilitecolor': this._setColor(e, command); break;
            case 'createlink' : this._createLink(command); break;
            default           : this._default(command, opt); break;
        }
        this.wnd.focus();
    },
    
    _default: function (command, opt) {
        if (!this.doc.queryCommandEnabled(command)) return;
        else this.doc.execCommand(command, false, opt); 
    },
    
    _createLink: function (command) {
        var szURL = prompt('Enter a URL:', '');
        if (!this.doc.queryCommandEnabled(command)) return;
        else this.doc.execCommand('CreateLink', false, szURL);
    },
    
    _setColor: function (e, command) {
        this.command = command;
        PaletteWindow.path = this.path;
        PaletteWindow.show(e);
        PaletteWindow.onPicked = function (color) {
            if (this.command==undefined) return;
            this.wnd.focus();
            if(this.isIE() && this.command == 'hilitecolor') 
                this.command = 'backcolor';
            if (!this.doc.queryCommandEnabled(this.command)) return;
            else this.doc.execCommand(this.command, false, color);
            this.wnd.focus();
        }.bind(this);
    },
    
    _insertTable: function () {
        colstext = prompt('Enter the number of columns per row.');
        rowstext = prompt('Enter the number of rows to create.');
        rows = parseInt(rowstext,'0');
        cols = parseInt(colstext,'0');
        if((rows <= 0) || (cols <= 0)) return;
        var table = new Element('table', {border: '1'});
        var tbody = new Element('tbody', {});
        for(var i=0; i<rows; i++){
            var tr = new Element('tr');
            for(var j=0; j<cols; j++){
                var td = new Element('td', {});
                td.innerHTML = '&nbsp;';
                tr.appendChild(td);
            }; tbody.appendChild(tr);
        }; table.appendChild(tbody);
        this._insertElement(table);
    },
    
    _insertElement: function (elem) {
        var sel = this.wnd.getSelection();
        var range = sel.getRangeAt(0);
        var pos = range.startOffset;
        var container = range.startContainer;
        sel.removeAllRanges();
        range.deleteContents();
        if (container.nodeName == 'HTML')
            container = this.wnd.document.body;
        var afterNode = container.childNodes[pos];
        container.insertBefore(elem, afterNode);
    },
    
    _insertImage: function () {
        var img = prompt('Image URL: ', 'http://');
        if (img=='http://') return;
        try {
            if (!this.doc.queryCommandEnabled('insertimage')) return;
            else this.doc.execCommand('insertimage', false, img); 
        } catch (e) {};
    },
    
    _viewSource: function () {
        $(this.id+'_textarea').value = this.getContent();
        var _h = $(this.id+'_container').getHeight();
        $(this.id+'_textarea').style['height'] = _h + 'px';
        $(this.id+'_container').hide();
        $(this.id+'_source').show();
        this.isPreview = false;
    },
    
    _preview: function () {
        this.setContent($(this.id+'_textarea').value);
        $(this.id+'_source').hide();
        $(this.id+'_container').show();
        this.isPreview = true;
    },
    
    isIE: function () {
        if(typeof(document.all)=='object') return true;
        return false;
    }

}

var PaletteWindow = {
    colors : [
        'FFFFFF', 'FFCCCC', 'FFCC99', 'FFFF99', 'FFFFCC', 
        '99FF99', '99FFFF', 'CCFFFF', 'CCCCFF', 'FFCCFF',
        'CCCCCC', 'FF6666', 'FF9966', 'FFFF66', 'FFFF33', 
        '66FF99', '33FFFF', '66FFFF', '9999FF', 'FF99FF',
        'C0C0C0', 'FF0000', 'FF9900', 'FFCC66', 'FFFF00', 
        '33FF33', '66CCCC', '33CCFF', '6666CC', 'CC66CC',
        '999999', 'CC0000', 'FF6600', 'FFCC33', 'FFCC00', 
        '33CC00', '00CCCC', '3366FF', '6633FF', 'CC33CC',
        '666666', '990000', 'CC6600', 'CC9933', '999900', 
        '009900', '339999', '3333FF', '6600CC', '993399',
        '333333', '660000', '993300', '996633', '666600', 
        '006600', '336666', '000099', '333399', '841E4D',
        '000000', '330000', '663300', '663333', '333300', 
        '003300', '003333', '679AC5', 'D2E1EE', '878787'
    ],
    
    onPicked: function (value) {},
    
    show: function (e, onPicked) {
        this.onPicked = onPicked;
        var p = document.viewport.getScrollOffsets();
        var top = e.screenY + p[1];
        var left = e.screenX + p[0];
        var wndStyle = 'z-Index: 10010; ';
        wndStyle    += 'position: absolute;';
        wndStyle    += 'top: '+top+'px;';
        wndStyle    += 'left: '+left+'px;';
        wndStyle    += 'background-color: #fff;';
        wndStyle    += 'border: 1px solid #B6CDDD';
        var wndAtt = {id: 'PaletteWindow', style: wndStyle};
        this.wnd = new Element('div', wndAtt);
        this.shadow = new Element('div',{});
        this.wnd.appendChild(this._palette());
        document.body.insertBefore(this.wnd, document.body.childNodes[0]);
        document.body.insertBefore(this.shadow, document.body.childNodes[0]);
        document.body.insertBefore(this._overlay(), document.body.childNodes[0]);
        this.shadow.src = this.path+'/images/shadow.png';
        this.shadow.style['top'] = top + 'px';
        this.shadow.style['left'] = left + 'px';
        this.shadow.style['zIndex'] = '10009';
        this.shadow.style['opacity'] = 0.3;
        this.shadow.style['position'] = 'absolute';
        this.shadow.style['margin'] = '3px 3px 0 5px';
        this.shadow.style['width'] = this.wnd.getWidth() + 'px';
        this.shadow.style['height'] = this.wnd.getHeight() + 'px';
        this.shadow.style['backgroundColor'] = '#666';
    },
    
    _palette: function () {
        var tbl = new Element('table',{});
        for (var i=0; i<7; i++) {
            var tr = new Element('tr', {});
            for (var j=0; j<10; j++) {
                var td = new Element('td', {
                    id :     this.colors[i*10+j],
                    width:   '15', height: '15',
                    bgcolor: '#'+this.colors[i*10+j],
                    style:   'cursor: pointer;font-weight:bold;color:#FFF;text-align:center;'
                }); 
                if(td['id'] == '841E4D') td.innerHTML = 'A';                
                tr.appendChild(td);
                td.onclick = this._pick.bindAsEventListener(this);   
            } tbl.appendChild(tr);
        }
        return tbl;
    },
    
    _overlay: function () {
        var overlaystyle = '';
    	overlaystyle += 'margin: auto;';
    	overlaystyle += 'z-index: 10009;';
    	overlaystyle += 'top: 0; left: 0;';
    	overlaystyle += 'position: fixed;';
    	overlaystyle += 'width: 100%; height: 100%;';
    	overlaystyle += 'background-color: transparent;';
    	var att = {id:'PaletteOverlay', style: overlaystyle};
        this.overlay = new Element('div', att);
        this.overlay.onclick = this.close.bindAsEventListener(this);
        return this.overlay;
    },
    
    _pick: function (e) {
        if (typeof this.onPicked == 'function')
            this.onPicked('#'+e.target.id);
        this.close();
    },
    
    close: function () {
        try {
            this.wnd.remove();
            this.shadow.remove();
            this.overlay.remove();
        } catch (e) {}
    }
}

