var ClassTree =
{
    connect : function()
    {
        var element = $(this);

        $$(".class_tree .class").each(function(e) { e.setStyle({ opacity : 0.3}); });
        // find prev and next
        var connect = new Array();
        $w(element.className).each(function(e)
        {
            if (e.indexOf("prev_") == 0)
                $A(e.replace("prev_", "").split("_")).each(function(f) { connect.push(f.toUpperCase()); });
            if (e.indexOf("next_") == 0)
                $A(e.replace("next_", "").split("_")).each(function(f) { connect.push(f.toUpperCase()); });
        });
        
        connect.each(function(e)
        {
            var f = $("Class" + e);

            if (f)
                {
                    f.setStyle({ opacity : 1.0 });
                    ClassTree.link(element, f);
                }            
        });

        element.setStyle({ opacity : 1.0 });
    },

    disconnect : function(element)
    {
        $$(".class_tree .class").each(function(e) { e.setStyle({ opacity : 1.0}); });
        $("ClassTreeLink").update();
    },

    link : function(src, dst)
    {
        if (src && dst)
        {
            var srcxy = src.cumulativeOffset();
            var dstxy = dst.cumulativeOffset();
            
            var srcc = { x : 0, y : 0 };
            var dstc = { x : 0, y : 0 };

            srcc.y = srcxy.top + Math.floor(src.getHeight() / 2);
            dstc.y = dstxy.top + Math.floor(dst.getHeight() / 2);

            // determine connecting points
            if (srcxy.left < dstxy.left)
            {
                // src is at left of dst
                srcc.x = srcxy.left + src.getWidth();
                dstc.x = dstxy.left;
                // now try to draw lines
                ClassTree.draw(srcc, dstc);
            }
            else
            {
                // src is at right of dst
                srcc.x = srcxy.left;
                dstc.x = dstxy.left + dst.getWidth();
                // now try to draw lines
                ClassTree.draw(dstc, srcc);
            }
            
        }
    },
    
    draw : function(start, end)
    { 
        // starting point is always at left of ending point
        // break line down to three segments with two additional connections
        var c0 = { x : Math.floor((end.x - start.x) / 2) + start.x, y : start.y };
        var c1 = { x : Math.floor((end.x - start.x) / 2) + start.x, y : end.y };

        var lines = new Array();

        lines.push({ a : start, b : c0 });
        lines.push({ a : c0, b : c1 });
        lines.push({ a : c1, b : end });

        // draw lines 
        lines.each(function(e)
        {
            // create line
            var line = new Element("div", { "class" : "floating line" });
            
            if (e.a.x == e.b.x) // vertical line
                line.setStyle({ width: "1px", height : Math.abs(e.a.y - e.b.y) + "px" });
            else // horizontal line
                line.setStyle({ width: Math.abs(e.a.x - e.b.x) + "px", height : "1px" });

            // set position
            if (e.a.y < e.b.y) // starting point is above
                line.setStyle({ left : e.a.x + "px", top : e.a.y + "px" });
            else
                line.setStyle({ left : e.a.x + "px", top : e.b.y + "px" });

            $("ClassTreeLink").insert(line);
        });
    },


    rules :
    {
        ".BV_classtree_connect" : function(element)
        { 
            element.onmouseover = ClassTree.connect;
            element.onmouseout = ClassTree.disconnect;
        }
    }

};


var Search =
{
    position : "bottom",

    callback : null,

    close : function()
    {
        $("SearchResult").update();
        $("SearchContainer").hide();
    },

    clear : function()
    {
        $(this).value = "";
    },


    respondInput : function(r)
    {
        response = r.responseText.evalJSON(true);

        $("SearchResult").update();

        if (response.success)
        {

        }
        else
        {
            System.status($("SearchResult"), 2);
        }

        $("SearchResult").insert(response.msg);

        if (Search.position != "bottom") 
        {
            var dx = 0 + $("SearchInput").getWidth() - $("SearchResult").getWidth();
            var dy = 0 - $("SearchResult").getHeight() - 20;

            System.showAt($("SearchContainer"), $("SearchInput"), { x : dx, y : dy });
        }
        else
        {
            System.showAt($("SearchContainer"), $("SearchInput"), { x : 0, y : 20 });
        }

        if (Search.callback != null)
        Search.callback();
    },


    input : function()
    {
        if ($F("SearchInput").empty())
        return false;

        $("SearchContainer").show();

        var e = $("SearchResult");
        e.update();
        System.loading(e);

        System.ajax(this.href,
            {
                method : "post",
                parameters : { input : $F("SearchInput") },
                onSuccess : Search.respondInput
            });
        return false;

    },


    enterInput : function(ev)
    {
        if (ev.keyCode == Event.KEY_RETURN)
        {
            var el = ev.element().up().down(".BV_search_input");
            el.onclick();
        }
    },

    rules :
    {
        ".BV_search_close" : function(element) { element.onclick = Search.close;  },
        ".BV_search_clear" : function(element) 
        { 
            element.onfocus = Search.clear;  
            $(element).observe("keyup", Search.enterInput);
        },

        ".BV_search_input" : function(element) { element.onclick = Search.input;  }
    }
};





var Achievement =
{

    effects : new Hash(),

    hover : function()
    {
        var type = this.href.split("/").pop();

        if (System.isset(Achievement.effects.get(type)) == true)
        {
            Achievement.effects.get(type).cancel();
        }

        var e = $(this).up(".menu_item");
        e.setOpacity(1);
    },

    fade : function(element)
    {
        var type = element.href.split("/").pop();
        var e = element.up(".menu_item");

        Achievement.effects.set(type, 
                                new Effect.Fade(e, 
                                { 
                                    duration : 0.5,
                                        from : 1, 
                                        to : 0.3
                                        })
                                );
    },

    out : function()
    {
        Achievement.fade($(this));
    },
    
    hideall : function()
    {
        $$(".BV_achiev_menu_item").each(Achievement.fade);
    },


    rules :
    {
        ".BV_achiev_menu_item" : function(element) 
        { 
            element.onmouseover = Achievement.hover; 
            element.onmouseout = Achievement.out;
        }
    }
};





System.register(ClassTree.rules);
System.register(Search.rules);
System.register(Achievement.rules);
