//TODO replace anchor with spans formatted to look the same as anchors, this
//will allow mousedrag selections inside anchors
var RRMark2 = function()
{
    var editor = 0;
    var to_edit = null;

    var editables = new Array();
    var finderActive = 0;
    var ignore_until = 0;

    var newPositionCallback;
    var mousedown_on = null;

    //whether we're currently making a selection (actually just if the mouse is
    //down)
    var selecting = 0;

    var current_div = null;

    var _pub = {
        init: function()
        {
            //load();
            textareas = $$('textarea.richierich');
            textareas.each(function(textarea){
                var div = new Element('div',{'class':'editable'});
                textarea.insert({before:div});
                div.innerHTML = textarea.value;
                Event.observe(div,"click",function(ev){ev.stop();});
                Event.observe(div,"dblclick",function(ev){
                    Editor.hideBlinkers();

                    var el = ev.element();
                    if(el.match('p.add_content'))
                    {
                        Util.removeChildren(el);
                        to_edit = document.createTextNode('');
                        el.appendChild(to_edit);
                    }
                    editor = 1;
                    Editor.edit(to_edit,RRMark2.finishEdit);
                });
                Event.observe(div,"mousedown",mouseDown);
                div.history = new History(div);
                Format.ensureIntegrity(div);
                textarea.toggle();
                //var savebutton = $('save_' + textarea.id.substr(9));
                var savebutton = textarea.up().next().childNodes[1];
                savebutton.disable();
                div.savebutton = savebutton;
                Event.observe(savebutton,'click',function()
                {
                    $$('p.add_content').each(function(p){p.remove()});
                    textarea.value = div.innerHTML;
                    Format.ensureIntegrity(div);
                });
            });
            Event.observe(document,"mousemove",mouseMove);
            Event.observe(document,"mouseup",mouseUp);
            //Event.observe($('mouseup_catcher'),"mouseup",mouseUp);

            newPositionCallback = Selection.hilight;

            Pallette.init();
        },

        dropImage: function(element)
        {
            if(!element)
            {
                var image = document.createElement('img');
                image.src = 'richierich.gif';
            }
            else
            {
                //element.remove();
                var image = element;
            }

            Dropper.beginDrop(image);
            newPositionCallback = Dropper.updateDrop;
            Wrapper.free();
        },

        selectInProgress: function()
        {
            return selecting;
        },

        finishEdit: function(nodes)
        {
            Debug.log('finishedit');
            editor = 0;
            Format.ensureIntegrity(current_div);
            if(nodes)
            {
                Wrapper.free('selected',nodes);
                Selection.activate(nodes,1);
            }
            else
                Selection.activate(Wrapper.get('selected'),1);
            Pallette.refresh(current_div);
        }
    };

    var mouseDown = function(e)
    {
        if(!e.isLeftClick() || e.shiftKey)
            return;
        var target = e.element();
        selecting = 1;

        if(!target.match('div.marker'))
            Editor.hideBlinkers();

        if(tmp = target.up('div.editable'))
            current_div = tmp;

        if(target.hasClassName('wrapper'))
            target = target.parentNode;

        if(target.match('a') || target.match('img'))
            selecting = 0;
        else if(target.up('a,img'))
            selecting = 0;

        //cant free the wrapper because the selection has already started and is
        //inside the wrapper.. freeing it will destroy the selection
        Wrapper.hide();
        if(!selecting)
        {
            var tmp = target.up('a');
            if(tmp && !target.match('img'))
                mousedown_on = tmp;
            else
                mousedown_on = target;
            
            if(target.match('img'))
            {
                var d = new Date();
                if(d.getTime() - target.mousedown_time < 500)
                {
                    //hax because dblclicks arent detected with all the screwing
                    //around
                    Editor.edit(target,RRMark2.finishEdit);
                    target.mousedown_time = 0;
                }
                else
                    target.mousedown_time = d.getTime();
            }
            if(!Util.ctrlKey(e))
                Wrapper.free();
        }
    };

    var mouseUp = function(e)
    {
        if(!e.isLeftClick() || e.shiftKey)
            return;
        Wrapper.show();
        if(Dropper.dropping())
        {
            Dropper.endDrop();
            newPositionCallback = Selection.hilight;
        }
        else if(!selecting)
        {
            var target = e.element();
            var tmp = target.up('a');
            if(tmp && !target.match('img'))
                target = tmp;
            if(mousedown_on == target)
            {
                if(target.match('a') || target.up('a'))
                {
                    to_edit = Selection.getHilighted();
                    Selection.activate(to_edit,Util.ctrlKey(e));
                }
                else
                {
                    to_edit = target;
                    Selection.activate(to_edit,Util.ctrlKey(e));
                }
            }
            else if(!target.match('#pallette') && !target.match('#editor') && !target.up('#pallette,#editor'))
            {
                to_edit = null;
                Wrapper.free();
                Pallette.refresh(current_div);
            }
            else
                return;
        }
        else
            handleSelection(e);

        selecting = 0;
        mousedown_on = null;
    };

    var handleSelection = function(e)
    {
        var range;
        if(window.getSelection())
        {
            range = window.getSelection().getRangeAt(0);
            if(range)
            {
                if(range.toString().length)
                {
                    var start = Wrapper.originalOffset(range.startContainer,range.startOffset);
                    var end = Wrapper.originalOffset(range.endContainer,range.endOffset);
                    var selected = Selection.getTextNodes(range);
                    if(selected)
                        setTimeout(hax.bind({s:start,e:end,nodes:selected}),5);
                }
                else
                {
                    //zero-length selection, this was actually just a click, so
                    //activate whatever the selection was in
                    to_edit = Wrapper.originalTextNode(range.startContainer);
                    Selection.activate(to_edit,Util.ctrlKey(e));
                }
                //Debug.log('collapsing selection');
                range.collapse(0);
                range.detach();
            }
        }
    };

    var hax = function()
    {
        Wrapper.free();
        if(editor)
        {
            editor = 0;
            return;
        }
        var start = this.s;
        var end = this.e;
        var selected = this.nodes;
        var n = 0;
        var left,right,parent;
        var to_activate = new Array();

        if(selected.length == 1)
        {
            if(start== 0 && end== selected[0].data.length)
            {
                to_activate.push(selected[0]);
            }
            else
            {
                var mid;
                parent = selected[0].parentNode;
                left = document.createTextNode(selected[0].data.substr(0,start));
                mid = document.createTextNode(selected[0].data.substr(start,end-start));
                right = document.createTextNode(selected[0].data.substr(end));
                parent.insertBefore(left,selected[0]);
                parent.insertBefore(mid,selected[0]);
                parent.insertBefore(right,selected[0]);
                parent.removeChild(selected[0]);
                to_activate.push(mid);
            }
        }
        else
        {
            parent = selected[0].parentNode;
            left = document.createTextNode(selected[0].data.substr(0,start));
            right = document.createTextNode(selected[0].data.substr(start));
            parent.insertBefore(left,selected[0]);
            parent.insertBefore(right,selected[0]);
            parent.removeChild(selected[0]);
            to_activate.push(right);
            for(n = 1;n < selected.length-1;n++)
                to_activate.push(selected[n]);
            if(selected[n])
            {
                parent = selected[n].parentNode;
                left = document.createTextNode(selected[n].data.substr(0,end));
                right = document.createTextNode(selected[n].data.substr(end));
                parent.insertBefore(left,selected[n]);
                parent.insertBefore(right,selected[n]);
                parent.removeChild(selected[n]);
                to_activate.push(left);
            }
        }

        Selection.activate(to_activate,1);
    };

    var mouseMove = function(e)
    {
        if(e.element().match('div.marker'))
            return;

        var new_div = null;
        if(e.element().match('div.editable'))
            new_div = e.element();
        else if(tmp = e.element().up('div.editable'))
            new_div = tmp;

        if(!new_div)
        {
            Wrapper.free('hilighted');
            Selection.deHilight();
            Editor.hideBlinkers();
            return;
        }

        if(!Wrapper.get('selected').length)
        {
            if(new_div && new_div != current_div)
            {
                current_div = new_div;
                Pallette.refresh(current_div);
            }
        }
        if(!current_div)
            return;
        //Debug.set('current_div',current_div.identify());

        if(mousedown_on && mousedown_on.match('img'))
        {
            var range = window.getSelection().getRangeAt(0);
            range.detach();

            current_div.history.push('move image');
            var a = mousedown_on.up('a');
            if(a && a.childNodes.length == 1)
            {
                mousedown_on.removeClassName('floatLeft');
                mousedown_on.removeClassName('floatRight');
                RRMark2.dropImage(a);
            }
            else
                RRMark2.dropImage(mousedown_on);
            mousedown_on = null;
            return;
        }

        if(finderActive || selecting)
            return;
        else if (e.timeStamp < ignore_until)
            return;
        var d = new Date();
        var time_offset = d.getTime()-e.timeStamp;
        finderActive = 1;

        var el = e.element();
        if(!Dropper.dropping() && el.tagName.toLowerCase() == 'img' && !el.parentNode.hasClassName('dropper'))
        {
            Editor.hideBlinkers();
            Selection.hilight(el);
        }
        else if(newPositionCallback)
            newPositionCallback(e,Util.findCursor(e.pointerX(),e.pointerY(),new_div));

        ignore_until = d.getTime() - time_offset;
        finderActive = 0;
    };

    //kinda swiped from scriptaculous, doesnt work though
    var load = function()
    {
        alert('load');
        var scripts = document.getElementsByTagName('script');
        var path = null;
        for(var n = 0;n < scripts.length;n++)
            if(scripts[n].src.match(/rr2\.js(\?.*)?$/))
            {
                path = scripts[n].src.replace(/rr2\.js(\?.*)?$/,'');
                break;
            }
        if(path)
        {
            var components = new Array(
                'config',
                'util',
                'debug',
                'textnode',
                'wrapper',
                'pallette',
                'dropper',
                'editor',
                'selection',
                'format',
                'history');
            components.each(function(c){
                document.write('<script type="text/javascript" src="'+path+c+'.js"><\/script>');
            });
        }
        alert('load done');
    };

    return _pub;
}();

window.onload = RRMark2.init;
