var solaceApi = {
    API_URL: "/answers/api/1.0",

    get: function(uri, options, callbacks){
        if(!options)options={};
        options["format"] = "json";

        var params = {
            url: solaceApi.API_URL + uri,
            content: options,
            headers: {"Accept": "application/json"},
            handleAs: "json-comment-optional"
        };

        if(callbacks){
            if(callbacks.load){
                params.load = callbacks.load;
            }
            if(callbacks.error){
                params.error = callbacks.error;
            }
        }

        dojo.xhrGet(params);
    },

    post: function(uri, data, callbacks, sync){
        if(!data) data = {};
        if(!sync) sync = false;

        var params = {
            url: solaceApi.API_URL + uri + "?format=json",
            content: data,
            sync: sync,
            headers: {"Accept": "application/json"},
            handleAs: "json-comment-optional"
        };

        if(callbacks){
            if(callbacks.load){
                params.load = callbacks.load;
            }
            if(callbacks.error){
                params.error = callbacks.error;
            }
        }

        dojo.xhrPost(params);
    }
};

var outright = {
    URL: "/answers",
    currentDirectoryPage: { baseUrl: null, keyword: "" },

    initialize: function() {

        if(!outright.currentDirectoryPage.baseUrl) {
            outright.currentDirectoryPage.baseUrl = OutrightConfig["MEMBERS_ROOT_URL"] + "/";
        }

        outright.initTypeHereFields();
        outright.initSignupForms();
        outright.initLocationInputs();
    },

    initTypeHereFields: function() {

        dojo.query(".type-here-field").forEach(
            function(field){
                field.defaultText = field.value;
                dojo.connect(field, "onfocus", function(ev) {
                    if(field.value == field.defaultText)
                    {
                        field.value = "";
                    }
                    dojo.addClass(field, "type-here-selected");
                });
                dojo.connect(field, "onblur", function(ev) {
                    if(field.value == "")
                    {
                        field.value = field.defaultText;
                    }
                    setTimeout(
                        function(){
                            dojo.removeClass(field, "type-here-selected");
                        },
                        500);
                });
            }
        );
    },

    initSignupForms: function() {

        dojo.query(".signup-form").forEach(
            function(form){
                var divNewUser = dojo.query(".new-user-box", form)[0];
                var rbNewUser = dojo.query("input[type='radio'][value='new']", form)[0];
                var inputEmail = dojo.query("input[name='email']", form)[0];
                var inputPassword = dojo.query("input[name='password']", form)[0];
                var fields = dojo.query(".inline-signup-field", form);
                var divPost = form.parentNode.parentNode.parentNode;
                var divErrors = dojo.query(".form-errors", form)[0];
                var divFormNotes = dojo.query(".form-notes", form)[0];

                var createHiddenField = function(name){
                    var hf = document.createElement("input");
                    hf.type = "hidden";
                    hf.name = name;
                    form.appendChild(hf);
                    form["hf_" + name] = hf;
                };

                var adjustPostHeight = function(){
                    divErrors.style.display = "none";
                    if(form.getAttribute("autoheight") != "1"){
                        if(rbNewUser.checked){
                            divPost.style.height = "250px";
                            divPost.style.backgroundImage = "url('/static/images/bg-post-call-out-signup.png')";
                        }
                        else {
                            divPost.style.height = "225px";
                            divPost.style.backgroundImage = "url('/static/images/bg-post-call-out-signin.png')";
                        }
                    }
                };

                createHiddenField("user[email]");
                createHiddenField("user[password]");
                createHiddenField("user[password_confirmation]");
                createHiddenField("redirect_to");

                form.actualUrl = form.action;

                dojo.connect(form, "onsubmit", function(ev){
                    divErrors.innerHTML = "";
                    var v = new Validator([
                            {control: inputEmail, fn:Validation.isEmail, message: "The email is not valid."},
                            {control: inputPassword, message: "Please enter your password."}
                        ],
                        {
                            onConstraintFail: function(c) {
                                divErrors.innerHTML += "<div> - " + c.message + "</div>";
                            },
                            onValidationFail: function() {
                                divFormNotes.style.display = "none";
                                divErrors.style.display = "block";
                            },
                            onValidationSuccess: function() {
                                divErrors.style.display = "none";
                                divFormNotes.style.display = "block";
                            }
                        }
                    );
                    if(rbNewUser.checked){
                        v.addConstraints([
                            {control: dojo.query("input[name='company[name]']", form)[0], message: "Please enter the company name."},
                            {control: dojo.query("input[name='company[terms_of_service]']", form)[0], fn: Validation.isChecked, message: "You must agree to the terms of service."},
                        ]);
                    }
                    if(v.validate()){
                        form.action = rbNewUser.checked ? OutrightConfig["SSO_INLINE_REGISTRATION_URL"] : OutrightConfig["SSO_INLINE_LOGIN_URL"];
                        if(rbNewUser.checked){
                            form["hf_user[email]"].value = inputEmail.value;
                            form["hf_user[password]"].value = inputPassword.value;
                            form["hf_user[password_confirmation]"].value = inputPassword.value;
                        }

                        var returnParams = "";
                        fields.forEach(
                            function(f){
                                returnParams = (returnParams == "" ? "" : "&") + returnParams + f.name + "=" + encodeURI(f.value);
                            }
                        );
                        form["hf_redirect_to"].value = form.actualUrl + "?" + returnParams;
                    }
                    else{
                        dojo.stopEvent(ev);
                    }
                });

                dojo.query("input[type='radio']", form).onclick(function(ev){
                    divNewUser.style.display = ev.target.value == "new" ? "block" : "none";
                    adjustPostHeight();
                });

                fields.forEach(function(f){
                    f.defaultText = f.value;
                    dojo.connect(f, "onfocus", function(ev){
                        if(ev.target.value == ev.target.defaultText){
                            ev.target.value = "";
                        }
                        dojo.query(".inline-signup-form", form)[0].style.display = "block";
                        adjustPostHeight();
                    });
                });
            }
        );
    },

    initLocationInputs: function(){
        var updateLocationDropDown = function(f){
            if(f.dropdown.options){
                search = f.value.toLowerCase();
                var cnt = 0;
                var html = ""
                for(var i = 0; i < f.dropdown.options.length; i++){
                    var opt = f.dropdown.options[i];
                    if(opt[0].substr(0, search.length) == search){
                        html += "<div><a href='" + outright.currentDirectoryPage.baseUrl + opt[3] + "'>" + opt[2] + "</a></div>";
                        cnt++;
                        if(cnt == 8){
                            break;
                        }
                    }
                    else {
                        if(opt[0] > search){
                            break;
                        }
                    }
                }
                f.dropdown.innerHTML = html;
                if(f.focused && search.length){
                    f.dropdown.style.display = "block";
                }
            }
        };

        dojo.query(".input-location").forEach(function(f){
            f.dropdown = document.createElement("div");
            f.dropdown.className = "location-dropdown";
            f.dropdown.style.display = "none";
            f.parentNode.appendChild(f.dropdown);

            solaceApi.get("/_locations/" + outright.currentDirectoryPage.keyword, {}, {
                load: function(response){
                    f.dropdown.options = response.list;
                    updateLocationDropDown(f);
                }
            });

            dojo.connect(f, "onfocus", function(){
                var position = dojo.position(f);
                f.focused = true;
                dojo.style(f.dropdown, {
                    "left": position.x + "px",
                    "top": (position.y + position.h)  + "px",
                    "width": (position.w - 10) + "px"
                });
                updateLocationDropDown(f);
            });

            dojo.connect(f, "onblur", function(){
                f.focused = false;
                setTimeout(function(){
                    f.dropdown.style.display = "none";
                    }, 1000);
            });

            dojo.connect(f, "onkeyup", function(){
                updateLocationDropDown(f);
            });
        });
    },

    signupFormSubmit: function(ev){
        dojo.stopEvent(ev);
        return false;
    },

    /*
     * This function closes the box with messages and sends a command to remove them from the database
     */
    closeMessages: function(){
        dojo.byId('flash-messages').style.display='none';
        solaceApi.get("/_clear_messages/");
    },

    /*
     * This function deletes SSO cookie and redirects the user to /logout page at outright.com
     */
    signout: function()
    {
        document.cookie = OutrightConfig["SSO_COOKIE_NAME"] + "=; domain=" + OutrightConfig["SSO_COOKIE_DOMAIN"] + "; path=/";
        var url = document.location.href;
        url += (url.indexOf("?") == -1 ? "?" : "&") + "ref";
        document.location = url;
    },

    /*
        This function returns an URL for a Solace object serialized to json.
    */
    urlFor: function(obj, type)	{
        if(obj.permalink) {
            return OutrightConfig["COMMUNITY_URL"] + "/" + obj.permalink;
        }
        if(!type){
            type = obj["#type"];
        }
        switch(type){
            case "solace.question":
                return outright.URL + "/" + obj["slug"] + "-" + obj["id"];
            case "tag":
                return OutrightConfig["COMMUNITY_URL"] + "/tags/" + obj;
        }
        return outright.URL;
    },

    /*
        Retrieves a list of member's questions using AJAX call to Solace API
    */
    loadUserQuestions: function (data, offset, limit, order, callback){
         solaceApi.get(
             "/questions/user/" + data["user"],
             {
                 offset: offset,
                 limit: limit,
                 order: order
             },
             {
                 load: callback,
                 error: function(err) {/*alert(err); outright.displayMessageBox("Data cannot be retrieved.");*/return true}
             }
         );
    },

    /*
        Retrieves a list of member's answers using AJAX call to Solace API
    */
    loadUserReplies: function (data, offset, limit, order, callback){
         solaceApi.get(
             "/posts/user/" + data["user"],
             {
                 offset: offset,
                 limit: limit,
                 order: order
             },
             {
                 load: callback,
                 error: function(err) {/*alert(err); outright.displayMessageBoxdisplayMessageBox("Data cannot be retrieved.");*/return true;}
             }
         );
    },
    
    /*
        Retrieves a list of member's answers using AJAX call to Solace API
    */
    loadUserTweets: function (data, callback){
         solaceApi.get(
             "/twitter/" + data["user"],
             {},
             {
                 load: callback,
                 error: function(err) {/*alert(err); outright.displayMessageBoxdisplayMessageBox("Data cannot be retrieved.");*/return true;}
             }
         );
    },


    /*
     * Hides main content on the page. This function is being called when the search results are displayed.
     */
    hideContent: function()	{
        var cse = dojo.byId("cse");
        if(cse){
            var div = dojo.byId("outright-content");
            if(div) div.style.display = "none";

            cse.style.display = "block";
        }
    },

    /*
     *   Those functions allow to submit vote using AJAX request.
     */
    voteUp: function(post) { outright.setVote(post, 1); },
    voteDown: function(post) { outright.setVote(post, -1); },
    clearVote: function(post) { outright.setVote(post, 0); },
    setVote: function (post, vote){
        solaceApi.get(
            "/_set_vote/" + post + "/" + vote,
            {},
            {
                load: function(result){
                    if(result.result){
                        dojo.byId("vote-up-" + post).style.display = vote == 1 ? "none" : "inline";
                        dojo.byId("unvote-up-" + post).style.display = vote != 1 ? "none" : "inline";
                        dojo.byId("vote-down-" + post).style.display = vote == -1 ? "none" : "inline";
                        dojo.byId("unvote-down-" + post).style.display = vote != -1 ? "none" : "inline";
                        dojo.byId("votes-" + post).innerHTML = result.votes;
                    }
                    else{
                        outright.displayMessageBox(result.message);
                    }
                }
            }
        );
    },

    /*
        Displays a message to user.
        TODO: Display it in DHTML box instead of the plain message box.
    */
    displayMessageBox: function(message){
//        alert(message);
    return true;
    },

    /*
     * Flags the post as inappropriate
     */
    flagInappropriatePost: function(postId){
        solaceApi.get("/_flag_post/" + postId, {}, {load: function(){ outright.displayMessageBox("Thank you for informing us about the inappropriate content."); }});
    },

    /*
        Replaces placeholders with the actual values in the template.
    */
    templatize: function(templateHtml, data){
        var value = templateHtml;
        for(key in data)
        {
            value = value.replace("##" + key + "##", data[key]);
        }
        return value;
    },

    /*
        Formats a timespan retrieved from Solace. Timespan is a six-elements array that contains
        number of years, months, days, hours, munites and seconds passed between two dates.
    */
    format_timespan: function(ts)
    {
        var labels = ["year", "month", "day", "hour", "minute", "second"];
        var result = [];
        for(var i = 0; i < 6; i++)
        {
            if(ts[i] > 0)
            {
                result[result.length] = ts[i] + " " + labels[i] + (ts[i] > 1 ? "s" : "");
                if(result.length == 2) break;
            }
        }

        return result.length ? result.join(" ") : "0 seconds";
    },

     /*
      * Displays a given DOM element as a pop-up window on the top of the page.
      */
    showPopup: function(id)
    {
        var popup = dojo.byId(id);
        var ovl = dojo.byId("popup-overlay");
        ovl.style.display = "block";
        popup.style.display = "block";
        popup.style.left = Math.max(0, (ovl.clientWidth - popup.clientWidth) / 2) + "px";
        popup.style.top = Math.max(0, (ovl.clientHeight - popup.clientHeight) / 2) + "px";
    },

    /*
     * Hides a pop-up window
     */
    hidePopup: function(id)
    {
        document.getElementById("popup-overlay").style.display = "none";
        document.getElementById(id).style.display = "none";
    },

    /*
     * Sends feedback to the server.
     */
    sendFeedback: function()
    {
        dojo.xhrPost({
            url: "/scripts/send-feedback.php",
            content: {
                message: dojo.byId("feedback-message").value,
                from: dojo.byId("feedback-from").value
            },
            load: function(data){
                outright.hidePopup("feedback");
            }
        });
        return false;
    },

    /*
     * Show "send message" popup.
     * TODO: Implement this function
     */
    showSendMessagePopup: function(company_name,company_id)
    {
        document.getElementById("send-massage-to-id").value = company_id;
        document.getElementById("send-massage-to").innerHTML = company_name;
        document.getElementById("popup-overlay").style.display = "block";
        document.getElementById("send-massage").style.display = "block";
    },
    /*
     * Sends message to the server.
     */
    sendInternalMessage: function()
    {
        var subj = dojo.byId("send-massage-subj");
        if (subj.value == '') {
            subj.style.border = '1px solid red';
            dojo.byId("subj-error").style.display = 'block';
            return false;
        } else {
            subj.style.border = '1px solid #C3C3C3';
            dojo.byId("subj-error").style.display = 'none';
        }
        solaceApi.post(
             "/internal_mail/send/",
             {
                 recipient: dojo.byId("send-massage-to-id").value,
                 subject: dojo.byId("send-massage-subj").value,
                 message: dojo.byId("send-massage-message").value
             },
             {
                 load: function() {
                    outright.hidePopup("send-massage");
                    return false;
                },
                 error: function(err) {/*alert(err); outright.displayMessageBox("Data cannot be retrieved.");*/return true;}
             }
        );
        dojo.byId("send-massage-subj").value = '';
        dojo.byId("send-massage-message").value = '';
        return false;
    },
    /*
     * Sends bulk message to users.
     */
    sendBulkMessages: function()
    {
        var subj = dojo.byId("send-bulk-massage-subj");
        if (subj.value == '') {
            subj.style.border = '1px solid red';
            dojo.byId("bulk-subj-error").style.display = 'block';
            return false;
        } else {
            subj.style.border = '1px solid #C3C3C3';
            dojo.byId("bulk-subj-error").style.display = 'none';
        }
        var text = dojo.byId("send-bulk-massage-message");
        outright.hidePopup("send-bulk-massage");
        user_ids.forEach(
            function(id){
                outright.sendOneBulkMail(id,subj.value,text.value);
            }
        );   
        dojo.byId("send-bulk-massage-subj").value = '';
        dojo.byId("send-bulk-massage-message").value = '';
        return false;
    },

    sendOneBulkMail: function(to_id,subj,text)
    {
        solaceApi.post(
             "/internal_mail/send/",
             {
                 recipient: to_id,
                 subject: subj,
                 message: text
             },
             {
                 load: function() {
                     if (response.result == true) {
                        dojo.byId("bulk-progress").style.display = "block";
                        dojo.byId("bulk-progress").innerHTML += "|";
                    }
                    return true;
                },
                 error: function(err) {return true;}
             },
             true
        );

        return true;
    },
    /*
    *
    */
    replyInternalMessageThread: function(thread_id,text,callback)
    {
        solaceApi.post(
             "/internal_mail/reply/",
             {
                 thread: thread_id,
                 text: text
             },
             {
                 load: callback,
                 error: function(err) {/*alert(err); outright.displayMessageBox("Data cannot be retrieved.");*/return true;}
             }
        );
        return false;
    },

    /*
     * Remove message by id
     */
    removeInternalMessage: function(message_id,callback)
    {
        solaceApi.get(
             "/internal_mail/remove/"+message_id,
             {},
             {
                 load: callback(message_id),
                 error: function(err) {/*alert(err); outright.displayMessageBox("Data cannot be retrieved.");*/return true;}
             }
        );
        return false;
    },

    /*
     * Remove message thread by id
     */
    removeInternalMessageThread: function(thread_id,callback)
    {
        solaceApi.get(
             "/internal_mail/remove_thread/"+thread_id,
             {},
             {
                 load: callback,
                 error: function(err) {/*alert(err); outright.displayMessageBox("Data cannot be retrieved.");*/return true;}
             }
        );
        return false;
    },


    toggleCommentBox: function(p)
    {
        dojo.query(".new_reply", p.parentNode.parentNode)[0].style.display = "block";
        return false;
    },

    /*
        Retrieves a list of member's questions using AJAX call to Solace API
    */

    loadInternalMails: function (data, offset, limit, order, callback){
         solaceApi.get(
             "/internal_mail/",
             {
                 offset: offset,
                 limit: limit,
                 order: order
             },
             {
                 load: callback,
                 error: function(err) {/*alert(err); outright.displayMessageBox("Data cannot be retrieved.");*/return true;}
    }
         );
    },
    /*loadInternalMails: function (callback,offset,limit,order){
         solaceApi.get(
             "/internal_mail/",
             {
                 offset: offset,
                 limit: limit,
                 order: order
            },
             {
                 load: callback,
                 error: function(err) {alert(err); outright.displayMessageBox("Data cannot be retrieved.");}
  }
         );
    },*/
    loadMailById: function (id,callback){
         solaceApi.get(
             "/internal_mail/read_message/"+id,
             {},
             {
                 load: callback,
                 error: function(err) {/*alert(err); outright.displayMessageBox("Data cannot be retrieved.");*/return true;}
             }
         );
    },
    /*
        Set post rating
    */
    setTopicRating: function (topic_id, rating, callback){
         solaceApi.get(
             "/_set_rating/"+topic_id+"/" + rating,
             {},
             {
                 load: callback,
                 error: function(err) {/*alert(err); outright.displayMessageBox("Data cannot be retrieved.");*/return true;}
             }
         );
    },

    startExpertRatingsTest: function() {
        var html = dojo.query("html")[0];
        dojo.style("expertratings-test", {
            width: (html.clientWidth - 20) + "px",
            height: (html.clientHeight - 20) + "px"
        });
        dojo.byId("expertratings-test-frame").src=OutrightConfig.COMMUNITY_URL + "/directory/bookkeeper-test";
        outright.showPopup("expertratings-test");
    }
  }

/* Displays a list of objects with pagination. */

function PaginatedList(container, context, loadDataFunction, templateFunction, pageSize, defaultOrder){
    this.container = container;
    this.loadDataFunction = loadDataFunction;
    this.templateFunction = templateFunction;
    this.pageSize = pageSize;
    this.context = context;

    this.pageIndex = -1;
    this.order = defaultOrder;

    this.loadPage(0);
}

PaginatedList.prototype.reorder = function(order)
{
    this.order = order;
    this.loadPage(0);
}

PaginatedList.prototype.loadPage = function(pageIndex){
    var loader = this;
    //this.container.innerHTML = "";
    this.loadDataFunction(this.context, this.pageSize * pageIndex, this.pageSize, this.order, function(response){
        loader.pageLoaded(pageIndex, response);
    });
}

PaginatedList.prototype.pageLoaded = function(pageIndex, data){
    this.container.innerHTML = this.templateFunction(data);
}

function ISO8601ToDate(CurDate) {

    // Set the fragment expressions
    var S = "[\\-/:.]";
    var Yr = "((?:1[6-9]|[2-9][0-9])[0-9]{2})";
    var Mo = S + "((?:1[012])|(?:0[1-9])|[1-9])";
    var Dy = S + "((?:3[01])|(?:[12][0-9])|(?:0[1-9])|[1-9])";
    var Hr = "(2[0-4]|[01]?[0-9])";
    var Mn = S + "([0-5]?[0-9])";
    var Sd = "(?:" + S + "([0-5]?[0-9])(?:[.,]([0-9]+))?)?";
    var TZ = "(?:(Z)|(?:([\+\-])(1[012]|[0]?[0-9])(?::?([0-5]?[0-9]))?))?";

    // RegEx the input
    // First check: Just date parts (month and day are optional)
    // Second check: Full date plus time (seconds, milliseconds and TimeZone info are optional)
    var TF;
    if ( TF = new RegExp("^" + Yr + "(?:" + Mo + "(?:" + Dy + ")?)?" +
    "$").exec(CurDate) ) {} else if ( TF = new RegExp("^" + Yr + Mo + Dy + "T" +
    Hr + Mn + Sd + TZ + "$").exec(CurDate) ) {};

    // If the date couldn't be parsed, return null
    if ( !TF ) {
    return null;
    };

    // Default the Time Fragments if they're not present
    if ( !TF[2] ) { TF[2] = 1 } else { TF[2] = TF[2] - 1 };
    if ( !TF[3] ) { TF[3] = 1 };
    if ( !TF[4] ) { TF[4] = 0 };
    if ( !TF[5] ) { TF[5] = 0 };
    if ( !TF[6] ) { TF[6] = 0 };
    if ( !TF[7] ) { TF[7] = 0 };
    if ( !TF[8] ) { TF[8] = null };
    if ( TF[9] != "-" && TF[9] != "+" ) { TF[9] = null };
    if ( !TF[10] ) { TF[10] = 0 } else { TF[10] = TF[9] + TF[10] };
    if ( !TF[11] ) { TF[11] = 0 } else { TF[11] = TF[9] + TF[11] };

    // If there's no timezone info the data is local time
    if ( !TF[8] && !TF[9] ) {
    return new Date(TF[1], TF[2], TF[3], TF[4], TF[5], TF[6], TF[7]);
    };
    // If the UTC indicator is set the date is UTC
    if ( TF[8] == "Z" ) {
    return new Date(Date.UTC(TF[1], TF[2], TF[3], TF[4], TF[5], TF[6],
    TF[7]));
    };
    // If the date has a timezone offset
    if ( TF[9] == "-" || TF[9] == "+" ) {
    // Get current Timezone information
    var CurTZ = new Date().getTimezoneOffset();
    var CurTZh = TF[10] - ((CurTZ >= 0 ? "-" : "+") +
    Math.floor(Math.abs(CurTZ) / 60))
    var CurTZm = TF[11] - ((CurTZ >= 0 ? "-" : "+") + (Math.abs(CurTZ) % 60))
    // Return the date
    return new Date(TF[1], TF[2], TF[3], TF[4] - CurTZh, TF[5] - CurTZm,
    TF[6], TF[7]);
    };

};

function monthNumberToString(i) {
    var month=new Array(12);
        month[0]="January";
        month[1]="February";
        month[2]="March";
        month[3]="April";
        month[4]="May";
        month[5]="June";
        month[6]="July";
        month[7]="August";
        month[8]="September";
        month[9]="October";
        month[10]="November";
        month[11]="December";
    return month[i];
}
function prepareNonZeroDate(i) {
    if (i.length == 1) {
       return '0'+i;
    }
    return i;
}
function htmlentities(string, quote_style) {
    var hash_map = {}, symbol = '', tmp_str = '', entity = '';
    tmp_str = string.toString();

    if (false === (hash_map = get_html_translation_table('HTML_ENTITIES', quote_style))) {
        return false;
    }
    hash_map["'"] = '&#039;';
    for (symbol in hash_map) {
        entity = hash_map[symbol];
        tmp_str = tmp_str.split(symbol).join(entity);
    }
    return tmp_str;
}
function get_html_translation_table (table, quote_style) {
    // Returns the internal translation table used by htmlspecialchars and htmlentities
    //
    // version: 1004.1212
    // discuss at: http://phpjs.org/functions/get_html_translation_table
    // +   original by: Philip Peterson
    // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   bugfixed by: noname
    // +   bugfixed by: Alex
    // +   bugfixed by: Marco
    // +   bugfixed by: madipta
    // +   improved by: KELAN
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   bugfixed by: Brett Zamir (http://brett-zamir.me)
    // +      input by: Frank Forte
    // +   bugfixed by: T.Wild
    // +      input by: Ratheous
    // %          note: It has been decided that we're not going to add global
    // %          note: dependencies to php.js, meaning the constants are not
    // %          note: real constants, but strings instead. Integers are also supported if someone
    // %          note: chooses to create the constants themselves.
    // *     example 1: get_html_translation_table('HTML_SPECIALCHARS');
    // *     returns 1: {'"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;'}

    var entities = {}, hash_map = {}, decimal = 0, symbol = '';
    var constMappingTable = {}, constMappingQuoteStyle = {};
    var useTable = {}, useQuoteStyle = {};

    // Translate arguments
    constMappingTable[0]      = 'HTML_SPECIALCHARS';
    constMappingTable[1]      = 'HTML_ENTITIES';
    constMappingQuoteStyle[0] = 'ENT_NOQUOTES';
    constMappingQuoteStyle[2] = 'ENT_COMPAT';
    constMappingQuoteStyle[3] = 'ENT_QUOTES';

    useTable       = !isNaN(table) ? constMappingTable[table] : table ? table.toUpperCase() : 'HTML_SPECIALCHARS';
    useQuoteStyle = !isNaN(quote_style) ? constMappingQuoteStyle[quote_style] : quote_style ? quote_style.toUpperCase() : 'ENT_COMPAT';

    if (useTable !== 'HTML_SPECIALCHARS' && useTable !== 'HTML_ENTITIES') {
        throw new Error("Table: "+useTable+' not supported');
        // return false;
    }

    entities['38'] = '&amp;';
    if (useTable === 'HTML_ENTITIES') {
        entities['160'] = '&nbsp;';
        entities['161'] = '&iexcl;';
        entities['162'] = '&cent;';
        entities['163'] = '&pound;';
        entities['164'] = '&curren;';
        entities['165'] = '&yen;';
        entities['166'] = '&brvbar;';
        entities['167'] = '&sect;';
        entities['168'] = '&uml;';
        entities['169'] = '&copy;';
        entities['170'] = '&ordf;';
        entities['171'] = '&laquo;';
        entities['172'] = '&not;';
        entities['173'] = '&shy;';
        entities['174'] = '&reg;';
        entities['175'] = '&macr;';
        entities['176'] = '&deg;';
        entities['177'] = '&plusmn;';
        entities['178'] = '&sup2;';
        entities['179'] = '&sup3;';
        entities['180'] = '&acute;';
        entities['181'] = '&micro;';
        entities['182'] = '&para;';
        entities['183'] = '&middot;';
        entities['184'] = '&cedil;';
        entities['185'] = '&sup1;';
        entities['186'] = '&ordm;';
        entities['187'] = '&raquo;';
        entities['188'] = '&frac14;';
        entities['189'] = '&frac12;';
        entities['190'] = '&frac34;';
        entities['191'] = '&iquest;';
        entities['192'] = '&Agrave;';
        entities['193'] = '&Aacute;';
        entities['194'] = '&Acirc;';
        entities['195'] = '&Atilde;';
        entities['196'] = '&Auml;';
        entities['197'] = '&Aring;';
        entities['198'] = '&AElig;';
        entities['199'] = '&Ccedil;';
        entities['200'] = '&Egrave;';
        entities['201'] = '&Eacute;';
        entities['202'] = '&Ecirc;';
        entities['203'] = '&Euml;';
        entities['204'] = '&Igrave;';
        entities['205'] = '&Iacute;';
        entities['206'] = '&Icirc;';
        entities['207'] = '&Iuml;';
        entities['208'] = '&ETH;';
        entities['209'] = '&Ntilde;';
        entities['210'] = '&Ograve;';
        entities['211'] = '&Oacute;';
        entities['212'] = '&Ocirc;';
        entities['213'] = '&Otilde;';
        entities['214'] = '&Ouml;';
        entities['215'] = '&times;';
        entities['216'] = '&Oslash;';
        entities['217'] = '&Ugrave;';
        entities['218'] = '&Uacute;';
        entities['219'] = '&Ucirc;';
        entities['220'] = '&Uuml;';
        entities['221'] = '&Yacute;';
        entities['222'] = '&THORN;';
        entities['223'] = '&szlig;';
        entities['224'] = '&agrave;';
        entities['225'] = '&aacute;';
        entities['226'] = '&acirc;';
        entities['227'] = '&atilde;';
        entities['228'] = '&auml;';
        entities['229'] = '&aring;';
        entities['230'] = '&aelig;';
        entities['231'] = '&ccedil;';
        entities['232'] = '&egrave;';
        entities['233'] = '&eacute;';
        entities['234'] = '&ecirc;';
        entities['235'] = '&euml;';
        entities['236'] = '&igrave;';
        entities['237'] = '&iacute;';
        entities['238'] = '&icirc;';
        entities['239'] = '&iuml;';
        entities['240'] = '&eth;';
        entities['241'] = '&ntilde;';
        entities['242'] = '&ograve;';
        entities['243'] = '&oacute;';
        entities['244'] = '&ocirc;';
        entities['245'] = '&otilde;';
        entities['246'] = '&ouml;';
        entities['247'] = '&divide;';
        entities['248'] = '&oslash;';
        entities['249'] = '&ugrave;';
        entities['250'] = '&uacute;';
        entities['251'] = '&ucirc;';
        entities['252'] = '&uuml;';
        entities['253'] = '&yacute;';
        entities['254'] = '&thorn;';
        entities['255'] = '&yuml;';
    }

    if (useQuoteStyle !== 'ENT_NOQUOTES') {
        entities['34'] = '&quot;';
    }
    if (useQuoteStyle === 'ENT_QUOTES') {
        entities['39'] = '&#39;';
    }
    entities['60'] = '&lt;';
    entities['62'] = '&gt;';


    // ascii decimals to real symbols
    for (decimal in entities) {
        symbol = String.fromCharCode(decimal);
        hash_map[symbol] = entities[decimal];
    }

    return hash_map;
}

function hightLightSubnav(menu) {
    document.getElementById('subnav-'+menu).style.background = '#B8D0D1';
}

dojo.addOnLoad(outright.initialize);
