/**
 * js file included in every page by default
 */


/**
 * System object
 * assemble some commonly used functions
 */


var System =
{
    onOverlayHide : "",


    // it only works for object property, do not use in this form : isset(var)
    isset : function(variable)
    {
        return (typeof(variable) != "undefined");
    },

    // clear element's inner html, all child nodes are removed
    // @param	object		dom element
    clear : function(element)
    {
        if (element)
        element.innerHTML = "";
    },

    // disable eleemnt's behaviour (onclick etc)
    // @param	object		dom element
    disable : function (element)
    {
        if (element)
        delete element.onclick;
    },


    update : function(data)
    {
        $H(data).each(function(pair)
            {
                $A($$(".PT_update_" + pair.key)).each(function(element)
                    {
                        if (pair.key == "progress_percent")
                        {
                            element.setStyle({ width : pair.value + "%"});
                        }
                        else
                        element.update(pair.value);
                    });
            });
    },

    showOverlayError : function(element, onhide)
    {
        if (!System.isset(onhide))
        onhide = function() {};

        var e = $("SystemOverlayError");
        e.update(element);
        System.showOverlay(e, onhide);
    },

    // enable overlay layer on page
    showOverlay : function (element, onhide)
    {
        var layer = $("SystemOverlay");

        if (layer)
        {

            if (element)
                {
                    var vx = document.viewport.getScrollOffsets()[0];
                    var vy = document.viewport.getScrollOffsets()[1];

                    var dw = document.viewport.getWidth();
                    var dh = document.viewport.getHeight();

                    var w = element.getWidth();
                    var h = element.getHeight();

                    if (dh <= 0)
                        dh = 600;

                    element.show();
                    element.setStyle({
                        left : Math.floor(dw / 2 - w / 2 + vx) + "px",
                            top : Math.floor(dh / 2 - h / 2 + vy) + "px"
                            });
                }

            layer.setStyle({
                top : "0px",
                    left : "0px",
                    width : (document.viewport.getWidth() - 20) + "px",
                    height : $$(".wireframe_100")[0].getHeight() + "px"
                    });

            System.onOverlayHide = onhide;

            new Effect.Appear(layer, { duration : 0.3, from : 0, to : 0.8 });
        }
    },

    hideOverlay : function()
    {
        var layer = $("SystemOverlay");

        if (layer)
        {
            if (System.onOverlayHide)
                System.onOverlayHide();
            $("SystemOverlayError").hide();
            new Effect.Fade(layer, { duration : 0.3 });
        }
    },

    // replace a dom element's content by loading message
    // @param	object		dom element
    // @return	void
    loading : function(element)
    {
        if (element)
        {
            element.insert(new Element("img", { src : "/image/template/phoenix/loading.gif",
                                                style : "vertical-align:top"
            }));
            element.insert(" loading...");
        }
    },

    // replace a dom element by an status button
    // @param	object		dom element
    // @param	int			type of status button (1-5)
    // @return void
    status : function(element, type)
    {
        if (element)
        element.insert(new Element('div', { "class" : "orb orb_c" + type }));
    },


    announce : function(element, msg)
    {
        if (element)
        {
            var e = new Element("span", { "class" : "c2 win" });
            e.insert(msg + "<br />");
            element.insert(e);
        }
    },

    // show element at position relative to another
    // @param	object		dom element
    // @param	object		at position
    // @param   object      x,y offset
    showAt : function(element, at, offset)
    {
        if (element && at)
        {
            element = $(element);
            at = $(at);

            if (!offset)
            offset = { x : 0, y : 0 };

            element.show();
            element.setStyle({ top : (at.cumulativeOffset().top + offset.y) + "px",
                                   left : (at.cumulativeOffset().left + offset.x) + "px" });
        }
    },

    inc : function(e, element)
    {
        if (element)
        var input = element.previous(".BV_system_value");
        else
        var input = this.previous(".BV_system_value");
        var m = ($("SystemMaxValue")) ? parseInt($("SystemMaxValue").value) : 10000;
        input.value = parseInt(input.value) + 1;

        if (input.value > m)
        input.value = m;

        return input.value;
    },

    dec : function(e, element)
    {
        if (element)
        var input = element.next(".BV_system_value");
        else
        var input = this.next(".BV_system_value");
        input.value = parseInt(input.value) - 1;
        if (input.value < 1)
        input.value = 1;

        return input.value;
    },


    showInfo : function()
    {
        var link = this.href.split("/");
        var id = link.pop();
        var type = link.pop();
        var info = $("SystemInfo" + type.capitalize() + id);
        if (info)
        {
            var e = $(this);
            var offset = { x : e.getWidth(), y : 0 };
            if (e.cumulativeOffset().left > document.viewport.getWidth() / 2)
                offset.x = 0 - info.getWidth();
            if (e.viewportOffset().top > document.viewport.getHeight() / 2)
                offset.y = 0 - info.getHeight();

            System.showAt(info, e, offset);
        }
    },

    hideInfo : function()
    {
        var link = this.href.split("/");
        var id = link.pop();
        var type = link.pop();
        var info = $("SystemInfo" + type.capitalize() + id);
        if (info)
        info.hide();
    },


    showTooltip : function()
    {
        var e = $(this);
        $w(e.className).each(function(str)
        {
            if (str.indexOf("tooltip_") == 0)
                {
                    var f = $("TextTooltip");
                    f.update(str.replace("tooltip_", "").capitalize());
                    var pos = Position.cumulativeOffset(e);
                    f.setStyle({ left : (pos[0] - f.getWidth() / 2 + e.getWidth() / 2) + "px",
                                     top : (pos[1] - f.getHeight()) + "px" });
                    f.show();
                }
        });

    },

    hideTooltip : function()
    {
        $("TextTooltip").hide();
    },

    active : function()
    {
        $(this).addClassName("bd1");
    },

    inactive : function()
    {
        $(this).removeClassName("bd1");
    },

    register : function(rules)
    {
        $H(rules).each(function(pair)
            {
                if (pair.key == "a" && Prototype.Browser.Gecko == false)
                    return;

                $$(pair.key).each(function(element)
                    {
                        pair.value(element);
                    });
            });

    },

    selectiveRegister : function(rules, container, filter)
    {
        $H(rules).each(function(pair)
            {
                if (filter.indexOf(pair.key) != -1)
                {
                    $$(container + " " + pair.key).each(function(element)
                        {
                            pair.value(element);
                        });
                }
            });

    },


    ajax : function(url, param, track)
    {
        new Ajax.Request(url, param);

        // track ajax
        if (typeof(pageTracker) != "undefined" && track != false)
        pageTracker._trackPageview();
    },


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

        if (response.success)
        {
            if (System.isset(response.updates))
                System.update(response.updates);
        }

        
        var e = $("SystemEditMsg");
        if (e)
        {
            e.update();
            if (response.success)
                System.status(e, 3);            
            else
                System.status(e, 2);
            e.insert(response.msg);
        }
    },



    field : function()
    {
        var f = $(this); // input
        f.hide();

        var e = f.previous(".BV_system_edit"); // span or a
        e.show();

        var s = f.value.escapeHTML();
        if (s.length <= 0)
        s = "Empty";

        if (System.isset(e.href) && e.innerHTML != s)
        {
            // auto save mode
            var g = $("SystemEditMsg");
            if (g)
                {
                    g.update();
                    System.loading(g);
                }
            System.ajax(e.href,
            {
                method : "post",
                    parameters : { data : f.value },
                    onSuccess : System.respondField
                        });
            return false;
        }
        else
        e.update(s);
    },

    edit : function()
    {
        var e = $(this);
        e.hide();

        var f = e.next(".BV_system_field");
        f.show();
        f.focus();
        return false;
    },

    respondGui : function(r)
    {
        response = r.responseText.evalJSON(true);
        
        if (response.success)
        {
            if (response.redirect)
                {
                    window.location = response.redirect;
                    return false;
                }
        }
        window.location.reload();
    },

    gui : function()
    {
        var e = $(this);
        e.insert({ after : new Element("img", { src : "/image/template/phoenix/loading.gif",
                                                    style : "vertical-align:top"
                                                    })
                       });
        e.hide();

        System.ajax(this.href,
            {
                method : "post",
                parameters : { gui : true },
                onSuccess : System.respondGui
            });
        return false;
    },


    center : function()
    {
        if (Prototype.Browser.Gecko)
        {
            $$(".body_center").each(function(element) { element.style.padding = "0 1px 0 0"; });
        }

        if (Prototype.Browser.WebKit)
        {
            $$(".body_center").each(function(element) { element.style.padding = "0 0 0 1px"; });
        }
    },

    rules :
    {
        "a" : function(element)
        {
            // remove firefox dotted border around <a> after click
            element.onfocus = function() { this.blur(); }
        },

        ".BV_overlay_hide" : function(element) { element.onclick = System.hideOverlay; },

        ".BV_system_file" : function(element)
        {
            element.onmouseover = System.showInfo;
            element.onmouseout = System.hideInfo;
            if (element.hasClassName("followable") == false)
            element.onclick = function() { return false; };
        },

        ".BV_tooltip_text" : function(element)
        {
            element.onmouseover = System.showTooltip;
            element.onmouseout = System.hideTooltip; //function() { System.clear(this); };
        },

        ".BV_system_highlight" : function(element)
        {
            element.onmouseover = System.active;
            element.onmouseout = System.inactive;
        },

        ".BV_system_gui" : function(element) { element.onclick = System.gui; },

        ".BV_home_bubble" : function(element)
        {
            element.onmouseover = function()
            {
                Dialog.show(this.innerHTML, $("HomeAvatar"), { x : 690, y : 55 }, "left");
            };

            element.onmouseout = Dialog.hide;

        },


        ".BV_system_inc" : function(element) { element.onclick = System.inc; },
        ".BV_system_dec" : function(element) { element.onclick = System.dec; },

        ".BV_system_field" : function(element) { element.onblur = System.field; },
        ".BV_system_edit" : function(element) { element.onclick = System.edit; }
    }
};


/**
 * authenticate object, present in most of pages
 */

var Auth =
{
    idDom :
    {
        form : "AuthForm",
        login : "AuthLogin",
        password : "AuthPassword",
        redirect : "AuthRedirect",
        submit : "AuthSubmit",
        error : "AuthError"
    },

    login : function()
    {
        System.clear($(Auth.idDom.error));
        System.loading($(Auth.idDom.error));
        $(Auth.idDom.submit).hide();

        var param = $(Auth.idDom.form).serialize(true);

        System.ajax($(Auth.idDom.form).action,
        {
            method : "post",
                parameters : { json : Object.toJSON(param) },
                onSuccess : Auth.respond
                });

    },

    logout : function()
    {
        System.loading($(Auth.idDom.error));
        $(Auth.idDom.submit).hide();

        System.ajax("/json/user/auth/logout",
        {
            onSuccess : Auth.respond
                });
    },

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

        if (response.success)
        {
            if ($(Auth.idDom.redirect))
                window.location = $F(Auth.idDom.redirect);
            else
                if (response.redirect)
                    window.location = response.redirect;
                else
                    window.location.reload();
        }
        else
        {
            $(Auth.idDom.submit).show();
            $(Auth.idDom.error).innerHTML = "";
            System.status($(Auth.idDom.error), 2);
            $(Auth.idDom.error).insert(response.error);
        }
    },

    rules :
    {
        ".BV_auth_login" : function(element)
        {
            element.onclick = function() { Auth.login(); };
        },

        ".BV_auth_logout" : function(element)
        {
            element.onclick = function() { Auth.logout(); };
        },

        "#AuthForm" : function(element)
        {
            element.onsubmit = function() { Auth.login(); return false; };
        }
    }

};



/**
 * Captcha (Completely Automated Public Turing test to tell Computers and Humans Apart) object
 * handle captcha related operations
 */
var Captcha =
{
    // refresh captcha image and optionally clear input field
    reload : function ()
    {
        var image = $(this.id.replace("Reload", "Image"));
        var input = $(this.id.replace("Reload", "Input"));

        if (image)
        {
            var time = new Date();
            image.src = "/imaged/captcha?" + time.getTime();
        }

        if (input)
        input.value = "";

    },

    rules :
    {
        ".BV_captcha_reload" : function(element) { element.onclick = Captcha.reload; }
    }
};



var Tab =
{
    index : function()
    {
        var header = $(this);
        var selected = $(this.id.replace("Tab", "TabContent"));
        if (header && selected)
        {
            header.adjacent(".BV_tab_index").each(function(element)
            {
                element.removeClassName("current");
                element.removeClassName("bg1");
            });
            header.addClassName("current");
            header.addClassName("bg1");

            selected.adjacent(".BV_tab_content").each(Element.hide);
            selected.show();
        }
        return false;
    },

    rules :
    {
        ".BV_tab_index" : function(element) { element.onclick = Tab.index; }
    }
};

var Toggle =
{
    show : function()
    {
        var expand = $(this);
        var id = this.id.replace("Toggle", "");
        var f = $("ToggleContent" + id);

        if (expand && f)
        {
            expand.hide();
            expand.adjacent(".BV_toggle_hide").each(Element.show);

            f.show();
        }

        return false;
    },


    hide : function()
    {
        var collapse = $(this);
        var id = "";

        if (collapse)
        {
            collapse.hide();
            collapse.adjacent(".BV_toggle_show").each(function(element)
            {
                id = element.id.replace("Toggle", "");
                element.show();
            });
        }

        var e = $("ToggleContent" + id);
        if (e)
        e.hide();

        return false;
    },

    rules :
    {
        ".BV_toggle_show" : function(element) { element.onclick = Toggle.show; },
        ".BV_toggle_hide" : function(element) { element.onclick = Toggle.hide; }
    }
};




var Filter =
{
    active : false,

    index : function()
    {
        if (Filter.active)
        {
            $$(".PT_filter_content").each(Element.show);
        }
        else
        {
            var filter = "";
            $w(this.className).each(function(str)
            {
                if (str.indexOf("filter_") == 0)
                    filter = str; // filter found
            });

            if (filter.length > 0)
            {
                $$(".PT_filter_content").each(function(element)
                {
                    if (!element.hasClassName(filter))
                        element.hide();
                });
            }
        }
        Filter.active = !(Filter.active);
    },

    rules :
    {
        ".BV_filter_index" : function(element) { element.onclick = Filter.index; }
    }
};

var Picker =
{
    inactive : new Hash(),

    index : function()
    {
        var filter = "";
        $w(this.className).each(function(str)
        {
            if (str.indexOf("picker_") == 0)
                filter = str.replace("picker_", ""); // filter found
        });

        if (filter.length > 0)
        {
            if (System.isset(Picker.inactive.get(filter)) == true)
                Picker.inactive.unset(filter);
            else
                Picker.inactive.set(filter, true);

            Picker.filter($(this), filter, !System.isset(Picker.inactive.get(filter)));
        }
        
        return false;
    },

    init : function(highlight)
    {
        Picker.none();
        $A(highlight).each(function(filter) 
            {
                Picker.inactive.unset(filter);
                $$(".picker_" + filter).each(function(e) { e.setOpacity(1); });
                $$(".PT_picker_" + filter).each(Element.show);
            });
    },
    
    filter : function(e, filter, show)
    {
        e.setOpacity(show ? 1 : 0.3);
        $$(".PT_picker_" + filter).each(show ? Element.show : Element.hide);
    },

    hide : function(element)
    {
        var filter = Picker.extract(element);

        Picker.inactive.set(filter, true);
        Picker.filter(element, filter, false);
    },
    

    show : function(element)
    {
        var filter = Picker.extract(element);
        Picker.inactive.unset(filter);
        Picker.filter(element, filter, true);
    },

    all : function()
    {
        $$(".PT_picker_all").each(Element.show);
        $$(".BV_picker_index").each(function(e) { e.setOpacity(1); });
        Picker.inactive = new Hash();
        return false;
    },

    extract : function(element)
    {
        var filter = "";
        $w(element.className).each(function(str)
        {
            if (str.indexOf("picker_") == 0)
                filter = str.replace("picker_", ""); // filter found
        });

        return filter;
    },
        
    none : function()
    {
        $$(".PT_picker_all").each(Element.hide);
        $$(".BV_picker_index").each(function(e) 
        { 
            var filter = Picker.extract(e);
            Picker.inactive.set(filter, true);
            e.setOpacity(0.3); 
        });

        return false;
    },
    
    rules :
    {
        ".BV_picker_all" : function(element) { element.onclick = Picker.all; },
        ".BV_picker_none" : function(element) { element.onclick = Picker.none; },
        ".BV_picker_index" : function(element) { element.onclick = Picker.index; }
    }

};

var Bubble =
{
    show : function(bubble, anchor)
    {

        if (anchor.cumulativeOffset().left > document.viewport.getWidth() / 2)
        {
            direction = "left";
            bubble.removeClassName("bubble_right");
            System.showAt(bubble, anchor, { x : 0 - bubble.getWidth(),
                                                y : 0 - bubble.getHeight() });

        }
        else
        {
            direction = "right";
            bubble.addClassName("bubble_right");
            System.showAt(bubble, anchor, { x : 0,
                                                y : 0 - bubble.getHeight() });
        }

    }

};



var Dialog =
{
    show : function(html, anchor, offset, direction)
    {
        if (!System.isset(offset))
        {
            offset = { x : 0, y : 0 };
        }

        if (!System.isset(direction))
        {
            direction = "right";
            if (anchor.cumulativeOffset().left > document.viewport.getWidth() / 2)
            direction = "left";
        }


        if ($("DialogBubble"))
        $("DialogBubble").remove();

        var d = new Element("div", { "class" : "dialog", id : "DialogBubble" });

        var inner = new Element("div", { "class" : "inner" });
        inner.insert(html);

        var middle = new Element("div", { "class" : "middle" });
        middle.insert(inner);

        d.insert(new Element("div", { "class" : "top" }));
        d.insert(middle);
        d.insert(new Element("div", { "class" : "bottom" }));

        var direct = new Element("div", { "class" : "direction direction_" + direction });
        d.insert(direct);


        var x = 0;
        var y = 0;
        var dx = 0;
        var dy = 0;

        switch (direction)
        {
        case "top" :
            break;
        case "left" :
            x = anchor.cumulativeOffset().left - 200 - 15;
            y = anchor.cumulativeOffset().top + 10;
            dx = 200 - 1;
            dy = 5;
            break;
        case "bottom" :
            break;
        case "right" :
            x = anchor.cumulativeOffset().left + anchor.getWidth() + 15;
            y = anchor.cumulativeOffset().top + 10;
            dx = -14;
            dy = 5;
            break;
        default :
        }

        x += offset.x;
        y += offset.y;

        d.setStyle({ top : y + "px", left : x + "px"});
        direct.setStyle({ top : dy + "px", left : dx + "px" });

        $$("body")[0].insert(d);
    },

    hide : function()
    {
        if ($("DialogBubble"))
        $("DialogBubble").hide();
    }

};


var Menu =
{
    timer : -1,
    hax : false,

    hideall : function()
    {
        $$(".wireframe_menu .dropdown").each(Element.hide);
    },

    show : function()
    {
        // some ie hax for scriptaculous
        if (Menu.hax && Prototype.Browser.IE)
        {
            if (Menu.timer != -1)
            window.clearTimeout(Menu.timer);
            Menu.hideall();
        }
        System.showAt($(this).down(".dropdown"), this, { x : 0, y : 12 });
    },

    hide : function()
    {
        // some ie hax for scriptaculous
        if (Menu.hax && Prototype.Browser.IE)
        {
            // wait a bit before hide
            Menu.timer = window.setTimeout(Menu.hideall, 200); 
        }
        else
        {
            $(this).down(".dropdown").hide();
        }
    },


    rules :
    {
        ".BV_menu_dropdown" : function(element)
        {
            element.onmouseover = Menu.show;
            element.onmouseout = Menu.hide;
        }

    }
};

var Generic =
{
    respond : function(r)
    {
        response = r.responseText.evalJSON(true);

        System.clear($("GenericMsg"));
        if (response.success)
        {
            System.status($("GenericMsg"), 3);
        }
        else
        {
            System.status($("GenericMsg"), 2);
            // some form needs to reload captcha
            $$(".BV_captcha_reload").each(function(element) { element.onclick(); });

            $("GenericSubmit").show();
        }

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


        if (System.isset(response.redirect))
        window.location = response.redirect;
    },


    rules :
    {
        ".BV_generic_submit" : function(element)
        {
            element.onclick = function()
            {
                $("GenericSubmit").hide();
                System.clear($("GenericMsg"));
                System.loading($("GenericMsg"));

                var param = $("GenericForm").serialize(true);

                System.ajax(this.href,
                {
                    method : "post",
                        parameters : { json : Object.toJSON(param) },
                        onSuccess : Generic.respond
                        });
                return false;
            };
        }
    }
};


var Notepad =
{
    shown : false,

    submit : function()
    {
        $(this).hide();
        $("AddonNotepadStatus").className = "orb orb_c1";

        System.ajax(this.href,
            {
                method : "post",
                parameters : { data : $("AddonNotepadContent").value },
                onSuccess : Notepad.respond
            });
        return false;
    },

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

        $$(".notepad .nolink").each(Element.show);
        $("AddonNotepadStatus").className = (response.success) ? "orb orb_c3" : "orb orb_c2";
    },

    show : function()
    {
        if (Notepad.shown == false)
        {
            System.showAt($("AddonNotepad"), $(this), { x : -360, y : 40 });
            Notepad.shown = true;
        }
        else
        Notepad.hide();
    },

    hide : function()
    {
        $("AddonNotepad").hide();
        Notepad.shown = false;
    },

    rules :
    {
        ".BV_notepad_save" : function(element) { element.onclick = Notepad.submit; },
        ".BV_notepad_show" : function(element) { element.onclick = Notepad.show; },
        ".BV_notepad_hide" : function(element) { element.onclick = Notepad.hide; }
    }
};


System.register(System.rules);
System.register(Auth.rules);
System.register(Captcha.rules);
System.register(Tab.rules);
System.register(Toggle.rules);
System.register(Filter.rules);
System.register(Picker.rules);
System.register(Menu.rules);
System.register(Generic.rules);
System.register(Notepad.rules);

