var TextEditor = new Class({
    initialize: function(params){
        this.TA = params.textarea || document.getElement('textarea');
        this.TB = new Element('div',{'class':'toolbar'});
        
        this.ieBookmark = null;
        this.btns = new Hash({
            'simple': ['face', null, 'strong','em','u',null,'img','link','unlink',null,'clean'],
            'standard': ['face', null, 'strong','em','u',null,'upload', 'img', 'vedio', 'link','unlink',null,'left','center','right',null,'clean'],
            'complete': ['face', null,'strong','em','u','superscript','subscript',null,'left','center','right','indent','outdent',null,'h1','h2','h3','p','ul','ol',null, 'upload', 'img','link','unlink',null,'clean','toggle']
        });
        this.version = params.version || 'simple';
        this.iframesrc = params.src || '/style/wysiwyg.html';
        this.editorSize = new Hash({
            'simple': [425, 100],
            'standard': [500, 200],
            'complete': [550, 250]
        });
        if(params.size){
            this.editorSize.set(this.version, params.size);
        }
        
        this.IF = new Element('iframe',{
            'frameborder':0,
            'src':this.iframesrc,
            'styles': {'height': this.editorSize.get(this.version)[1]}
         }).addEvents({
            'load': function(){
                this.doc = this.IF.contentWindow.document;
                if(Browser.Engine.trident){
                    this.addBookmarkEvent();
                }
                this.doc.designMode = 'on';
                this.toggleView();
            }.bind(this)
            
            //'blur': function() {this.toTextarea();}.bind(this)
         });
        
        this.CT = new Element('div',{'class':(params.klass||'wysiwyg')}).injectBefore(this.TA).adopt(this.TB,this.IF,this.TA);
        this.CT.setStyle('width', this.editorSize.get(this.version)[0]);

        this.open = false;
        $each(this.btns[this.version], function(b){
            if(!b){
                new Element('span',{'class':'spacer'}).inject(this.TB);
            }else{
                new Element('a',{'class':b,'href':'#'+b, 'text': b, 'title': _BUTTONS_DESC.get(b)}).addEvent('click',function(e){
                    e.stop();
                    b=='toggle' ? this.toggleView() : this.exec(b, e);
                }.bind(this)).inject(this.TB);
            }
        },this);
    },

    toggleView: function(){
        if($try(function(){if(this.doc.body){return true;}}.bind(this))){
            if(this.open){
                this.toTextarea(true);
            }else{
                this.toEditor(true);
            }
            this.open = !this.open;
        }
    },

    toTextarea: function(view){
        if(this.clean(this.doc.body.innerHTML).replace(/<.+?>/g, '').replace(/&nbsp;/g, '').replace(/ /g, '').length){
            this.TA.value = this.clean(this.doc.body.innerHTML);
        }
                
        if(view){
            this.TA.removeClass('hidden');
            this.IF.addClass('hidden');
            this.TB.addClass('disabled');
            this.TA.focus();
        }
    },
    
    parseVedioTag: function(html) {
    	return html.replace(/<embed.*?src="(.*?)".*?<\/embed>/gi, '<img src="/image/te_vedio.jpg?src=$1" />');
    },

    toEditor: function(view){
        var val = this.parseVedioTag(this.TA.value.trim());
        this.doc.body.innerHTML = val==''?'<p>&nbsp;</p>':val;
        if(view){
            this.TA.addClass('hidden');
            this.IF.removeClass('hidden');
            this.TB.removeClass('disabled');
        }
    },

    exec: function(b, e){
        if(this.open){
            this.IF.contentWindow.focus();
            but = _BUTTONS[b];
            var val = but[1];
            switch(but[2]){
                case 'http://':
                    this.pop(but, e);
                    break;
                case 'face':
                    this.showFace(but, e);
                    break;
                case 'upload':
                    this.iniUpload(but, e);
                    break;
                default:
                    this.doc.execCommand(but[0],false,val);            	
            }
        }
    },
    
    pop: function(but, e) {
        var tl = new TipLayer({'tpl': but[0],'data': {'desc': but[1], 'default': but[2]}}, e, {
            onGeted: function() {
                $(tl.options.cId).getElement('button[name=create]').addEvent('click', function(e) {
                    val = $(tl.options.cId).getElement('input[name=url]').get('value');
                    if(val != but[2]){
                        this.getBookmark();
                        if(but[1] == '插入视频'){
                            this.doc.execCommand(but[0], false, '/image/te_vedio.jpg?src=' + val);
                        }else{
                            this.doc.execCommand(but[0], false, val);
                        }
                        tl.destroy();
                    }
                }.bind(this));
            }.bind(this),
            width: 325
        });
    },
    
    iniUpload: function(but, e) {
        if($('ajax_upload_image')){
            $('ajax_upload_form').setStyle('display', 'block');
            $('ajax_upload_image').getElement('.process').setStyle('display', 'none');
            return;
        }
        new Request({
            //取得照片专辑分类
            url: '/photo/album/select/',
            method: 'post',
            onComplete: function(text) {
                if(text != 'false'){
                    this.uploadImage(but, e, text);
                }
            }.bind(this)
        }).send();
    },
    
    uploadImage: function(but, e, options) {
        var position = $(e.target).getPosition();
        var upload_form = new Element('div', {
            'id': 'ajax_upload_image',
            'class': 'ajax_upload_image',
            'html': TextEditor.templete.get('upload'),
            'styles': {'left': position.x, 'top': position.y + 15}
        });
        
        $(document.body).adopt(upload_form);
        $('ajax_upload_image').getElement('p.select').set('html', options);
        new FormCheck('ajax_upload_form');

        var upload= new AjaxUpload('ajax_upload_form', {
            onResponse: function(text) {
                if(text.status){
                    this.getBookmark();
                    this.doc.execCommand(but[0], false, text.url);
                    upload.finish();
                    $('ajax_upload_image').destroy();
                }else if(text.error){
                    alert(text.error);
                    upload.finish();
                    $('ajax_upload_image').destroy();
                }
            }.bind(this),
            onUpload: function(form) {
                form.setStyle('display', 'none');
                $('ajax_upload_image').getElement('.process').setStyle('display', 'block');
            }
        });
        //cancel event
        $('ajax_upload_form').getElement('button[name=cancel]').addEvent('click', function(e) {
            upload.finish();
            $('ajax_upload_image').destroy();
        });
    },
    
    buildFace: function(but) {
        var faceList = '';
        for(var i = 0, j = 30; i < j; i ++){
            faceList += new Template(TextEditor.templete.get('single')).parse({ 'id': i + 1 });
        }
        var faceEl = new Element('div', {
            'html': new Template(TextEditor.templete.get('base')).parse({ 'face_list': faceList }),
            'id': 'area_face_list',
            'class': 'live_face_list',
            'styles': {'display': 'none'}
        });
        $(document.body).adopt(faceEl);
        faceEl.getElements('li a').each(function(link) {
            link.addEvent('click', function(e) {
                e.stop();
                //console.info($(e.target));
                this.doc.execCommand(but[0], false, $(e.target).get('src'));
                $('area_face_list').setStyle('display', 'none');
            }.bind(this));
        }, this);
        
        $(document.body).addEvent('click', function(e) {
            $('area_face_list').setStyle('display', 'none');
        }.bind(this));
    },
    
    showFace: function(but, e) {
        if(!$('area_face_list')){
            this.buildFace(but);
        }
        var position = $(e.target).getPosition();
        //console.log(position);
        $('area_face_list').setStyles({
            'display': 'block',
            'left': position.x,
            'top': position.y + 15
        });
    },
    
    addBookmarkEvent: function() {
        this.doc.onbeforedeactivate = this.setBookmark.bind(this);
        //doc.onactivate = this.getBookmark.bind(this);
    },
    
    setBookmark: function() {
        var range = this.doc.selection.createRange();
        try{
            this.ieBookmark = range.getBookmark();
        }catch(e){}
        
    },
    
    getBookmark: function() {
        if(this.ieBookmark){
            var range = this.doc.body.createTextRange();
            range.moveToBookmark(this.ieBookmark);
            //range.collapse();
            range.select();
        }
    },

    clean: function(html){
        return html
        .replace(/\s{2,}/g,' ')
        .replace(/^\s+|\s+$/g,'')
        .replace(/\n/g,'')
        .replace(/<[^> ]*/g,function(s){return s.toLowerCase();})
        .replace(/<[^>]*>/g,function(s){s=s.replace(/ [^=]+=/g,function(a){return a.toLowerCase();});return s;})
        .replace(/<[^>]*>/g,function(s){s=s.replace(/( [^=]+=)([^"][^ >]*)/g,"$1\"$2\"");return s;})
        .replace(/<[^>]*>/g,function(s){s=s.replace(/ ([^=]+)="[^"]*"/g,function(a,b){if(b=='alt'||b=='href'||b=='src'||b=='title'||b=='style'){return a;}return'';});return s;})
        .replace(/<b(\s+|>)/g,"<strong$1")
        .replace(/<\/b(\s+|>)/g,"</strong$1")
        .replace(/<i(\s+|>)/g,"<em$1")
        .replace(/<\/i(\s+|>)/g,"</em$1")
        .replace(/<span style="font-weight: normal;">(.+?)<\/span>/gm,'$1')
        .replace(/<span style="font-weight: bold;">(.+?)<\/span>/gm,'<strong>$1</strong>')
        .replace(/<span style="font-style: italic;">(.+?)<\/span>/gm,'<em>$1</em>')
        .replace(/<span style="(font-weight: bold; ?|font-style: italic; ?){2}">(.+?)<\/span>/gm,'<strong><em>$2</em></strong>')
        .replace(/<img src="([^">]*)">/g,'<img src="$1" />')
        .replace(/(<img [^>]+[^\/])>/g,"$1 />")
        .replace(/<u>(.+?)<\/u>/gm,'<span style="text-decoration: underline;">$1</span>')
        .replace(/<font[^>]*?>(.+?)<\/font>/gm,'$1')
        .replace(/<font>|<\/font>/gm,'')
        .replace(/<br>\s*<\/(h1|h2|h3|h4|h5|h6|li|p)/g,'</$1')
        .replace(/<br>/g,'<br />')
        .replace(/<(table|tbody|tr|td|th)[^>]*>/g,'<$1>')
        .replace(/<\?xml[^>]*>/g,'')
        .replace(/<[^ >]+:[^>]*>/g,'')
        .replace(/<\/[^ >]+:[^>]*>/g,'')
        .replace(/(<[^\/]>|<[^\/][^>]*[^\/]>)\s*<\/[^>]*>/g,'');
    }
});

var _BUTTONS = {
    strong: ['bold',null],
    em: ['italic',null],
    u: ['underline',null],
    superscript: ['superscript',null],
    subscript: ['subscript',null],
    left: ['justifyleft',null],
    center: ['justifycenter',null],
    right: ['justifyright',null],
    indent: ['indent',null],
    outdent: ['outdent',null],
    h1: ['formatblock','<H1>'],
    h2: ['formatblock','<H2>'],
    h3: ['formatblock','<H3>'],
    p: ['formatblock','<P>'],
    ul: ['insertunorderedlist',null],
    ol: ['insertorderedlist',null],
    link: ['createlink','请输入一个链接地址：','http://'],
    unlink: ['unlink',null],
    img: ['insertimage','请输入一个图片地址：','http://'],
    face: ['insertimage', '插入表情', 'face'],
    upload: ['insertimage', '上传图片', 'upload'],
    vedio: ['insertimage', '插入视频', 'http://'],
    clean: ['removeformat',null],
    toggle: ['toggleview']
};

var _BUTTONS_DESC = new Hash({
    'strong': '加粗',
    'em': '斜体',
    'u': '下划线',
    'superscript': '上标注',
    'subscript': '下标注',
    'left': '左对齐',
    'center': '居中对齐',
    'right': '右对齐',
    'indent': '内缩近',
    'outdent': '外缩近',
    'h1': 'H1标题',
    'h2': 'H2标题',
    'h3': 'H3标题',
    'p': '段落',
    'ul': '不规则列表',
    'ol': '规则列表',
    'link': '插入链接',
    'unlink': '清除链接',
    'img': '插入图片',
    'face': '插入表情',
    'upload': '上传图片',
    'vedio': '引用视频',
    'clean': '清除格式',
    'toggle': '查看源代码'
});

var AjaxUpload = new Class({
    Implements: [Events, Options],
    options: {
        onUpload: $empty(),
        onResponse: $empty()
    },
    initialize: function(form, options) {
        this.setOptions(options);
        this.form = $(form);
        var enctype = this.form.encoding ? 'encoding' : 'enctype';
        this.form.set(enctype, 'multipart/form-data');
        this.form.set('method', 'post');
        this.form.set('action', this.options.action || this.form.get('action'));
        
        this.form.addEvent('submit', function(e) {
            this.fireEvent('onUpload', this.form);
        }.bind(this));
        
        this.frameId = 'upload_' + $time();
        this.target = new IFrame({
            src: Browser.Engine.trident ? 'javascript:false' : 'about:blank',
            styles: {
                width:0,
                height: 0,
                visibility: 'hidden',
                position: 'absolute'
            },
            name: this.frameId,
            id: this.frameId,
            events: {
                load: function() {
                    this.response();
                }.bind(this)
            }
        });
        $(document.body).adopt(this.target);
        this.form.set('target', this.frameId);
    },
    
    response: function() {
        var text = this.target.contentWindow.document.body.innerHTML;
        if(text){
            try{ text = JSON.decode(text);}catch(e){}
            //console.log(text);
            this.fireEvent('onResponse', text);
        }
    },
    
    finish: function() {
        try{this.target.destroy();}catch(e){}
    }
});

var te_check_photo = function(value) {
    var re = /\.(gif|jpg|jpeg|gif|png)$/i;
    return re.test(value);
};

TextEditor.templete = new Hash({
    base:
    '<div class="arrow_line"></div>' +
    '<ul class="clearfix">' +
    '%face_list%' +
    '</ul>',    
    single:
    '<li><a href="#" id="face%id%"><img src="/image/face/%id%.gif" /></a></li>',
    upload:
    '<div class="arrow_line">&nbsp;</div>' +
    '<div class="form">' +
        '<p class="process">图片上传中，请稍候...</p>' +
        '<form action="/photo/single/save/" method="post" enctype="multipart/form-data" id="ajax_upload_form">' +
            '<p><strong>请选择要上传图片和存放的图片专辑：</strong></p>' +
            '<p class="select"></p>' +
            '<p><input type="file" name="Filedata" size="33" class="photo_file form_check[te_check_photo(self,@上传的照片格式不对)]" id="image_file" /></p>' +
            '<p><button type="submit" name="upload"><b><i>上传</i></b></button><button type="button" name="cancel" class="g"><b><i>取消</i></b></button></p>' +
        '</form>' +
    '</div>'
});
























