var Util = function()
{
    var _pub = {
        ctrlKey: function(e)
        {
            if(e.ctrlKey || e.metaKey)
                return true;
            else
                return false;
        },

        findCursor: function(x,y,div)
        {
            var where = null;

            var verbose = 'findcursor ' + x + ' ' + y + '\n';

            var walker = div.firstDescendant();
            while(walker)
            {
                if(!walker.match('span.dropper'))
                {
                    var walker_pos = walker.cumulativeOffset();
                    var left = walker_pos.left + parseInt(walker.getStyle('padding-left'));
                    var right = left + walker.getWidth() - parseInt(walker.getStyle('padding-right'));
                    var top = walker_pos.top + parseInt(walker.getStyle('padding-top'));
                    var bottom = top + walker.getHeight() - parseInt(walker.getStyle('padding-bottom'));

                    /*
                    verbose += 'walked onto ' + walker.tagName + '\n';
                    verbose += 'top: ' + top + '\n';
                    verbose += 'left: ' + left + '\n';
                    verbose += 'bottom: ' + bottom + '\n';
                    verbose += 'right: ' + right + '\n';
                    */
                    if(y < top)
                    {
                        //Debug.set('where','above ' + Debug.summarise(walker));
                        where = {above:walker};
                        break;
                    }
                    else if(y >= top && y <= bottom)
                    {
                        //Debug.set('where','inside ' + Debug.summarise(walker));
                        where = {inside:walker};
                        break;
                    }
                    else
                    {
                        //Debug.set('where','below ' + Debug.summarise(walker));
                        where = {below:walker};
                    }
                }

                walker = walker.next();
            }

            //Debug.set('where_verbose',verbose);
            return where;
        },

        removeChildren: function(obj)
        {
            while(obj.childNodes.length)
                obj.removeChild(obj.firstChild);
        },

        createButton: function(label,title,callback,enabled,img_name)
        {
            var button;
            if(!img_name)
            {
                button = new Element('input');
                button.value = label;
                button.title = title;
                button.type = 'submit';
                if(!enabled)
                    button.disabled = 'true';
                else
                    Event.observe(button,'click',callback);
            }
            else
            {
                button = new Element('div').update(label);
                button.addClassName(img_name);
                if(enabled == 0)
                {
                    button.addClassName('disabled');
                }
                else if(enabled == 1)
                {
                    Event.observe(button,'mousedown',function(){
                        button.addClassName('depressed');
                        button.has_mouse = true;
                    });
                    Event.observe(button,'mouseover',function(){
                        button.has_mouse = true;
                    });
                    Event.observe(button,'mouseout',function(){
                        button.removeClassName('depressed');
                        button.has_mouse = false;
                    });
                    Event.observe(button,'mouseup',function(){
                        button.removeClassName('depressed');
                        if(button.has_mouse)
                        {
                            showPleaseWait();
                            //using this timeout avoids some weird bug..
                            setTimeout(function(){callback();hidePleaseWait()},1);
                        }
                    });
                }
                else
                    button.addClassName('midstate');
            }

            button.addClassName('button');

            return button;
        },

        //move children of src into dst and place dst before src, if dst is not
        //supplied will place children of src before src
        //removes src
        relocate: function(src,dst)
        {
            var parent = src.parentNode;

            if(dst)
            {
                dst = new Element(dst);
                while(src.firstChild)
                {
                    Debug.summarise(src.firstChild);
                    dst.appendChild(src.firstChild);
                }
                src.parentNode.insertBefore(dst,src);
            }
            else
            {
                while(src.firstChild)
                    parent.insertBefore(src.firstChild,src);
            }
            src.remove();
        },

        collectAncestors: function(nodes,selector)
        {
            var unsorted = new Array();
            nodes.each(function(node){
                if(node.parentNode)
                {
                    var testme = null;
                    if(node.nodeType == 3)
                        testme = node.parentNode;
                    else
                        testme = node;

                    var a = null;
                    if(Util.match(testme,selector))
                        a = testme;
                    else
                        a = testme.up(selector);

                    if(a)
                        unsorted.push(a);
                }
            });

            return Util.sort(unsorted.uniq());
        },

        //takes an array of elements (not textnodes!) and sorts them according
        //to document order
        //if the element types can be described with a css selector, pass it to
        //speed things up slightly
        sort: function(unsorted,selector)
        {
            var sorted = new Array();
            var all_elems;
            if(selector)
                all_elems = $$(selector);
            else
                all_elems = document.body.descendants();

            all_elems.each(function(elem){
                if(unsorted.indexOf(elem) != -1)
                    sorted.push(elem);
            });

            return sorted;
        },

        //same as above but handles textnodes only
        sortTextNodes: function(unsorted)
        {
            if(!unsorted || unsorted.length == 0)
                return unsorted;

            var sorted = new Array();
            var div = unsorted.first().parentNode.up('div.editable');
            var walker = div;
            while(walker = TextNode.nextLeaf(walker,div,
                'text',{skip_floating:true,skip_brs:true}))
                if(unsorted.indexOf(walker) != -1)
                    sorted.push(walker);

            return sorted;
        },

        match: function(node,selector)
        {
            if(!node)
                return 0;
            var selectors = selector.split(',');
            if(node.nodeType == 3)
            {
                if(selectors.indexOf('text') != -1)
                    return 1;
            }
            else
            {
                for(var n = 0;n < selectors.length;n++)
                    if(node.match(selectors[n]))
                        return 1;
            }
            return 0;
        },

        attached: function(node)
        {
            while(node)
            {
                node = node.parentNode;
                if(node == document.body)
                    return true;
            }
            return false;
        }
    };

    var showPleaseWait = function()
    {
        /*
        var fader = $('fader');
        if(!fader)
        {
            fader = new Element('div');
            fader.id = 'fader';
        }
        document.body.appendChild(fader);
        */

        var pleasewait = new Element('div').update('Please wait..');
        pleasewait.id = 'pleasewait';

        document.body.appendChild(pleasewait);
    };

    var hidePleaseWait = function()
    {
        $('pleasewait').remove();
        //$('fader').remove();
    };

    return _pub;
}();
