/**
 * Base.js - Start of all js for Menu.
 */
// Set up the new namespacing
var Menu = Menu || {};
var T_menu_init = null;

DEBUG = false;

/**
 * This is the load point for all on page load functions
 * they are wrapped around functionality to make sure the
 * page is ready before anything is executed.
 */
Menu.init = function ()
{
    // When the page is finished loading...
    Event.observe(window, 'load', function () {
    
        // Register the events that will fire every time 
        // a certain AJAX event occurs.
        Ajax.Responders.register({
            onComplete: function () {
                
                // Also, make sure you update the menu history navigation for
                // the new elements
                if (typeof reinitializeDashboardView!= "undefined") {
                    reinitializeDashboardView();
                }
                
            }
            
        });
        
        // Register any other events that should happen
        Event.observe(window, 'resize', function () {
            clearTimeout(T_menu_init);
            T_menu_init = setTimeout(Menu.setFooterPosition, 50);
        });
       
        // are there page controls?
        var is_page_controls = false;
        if ($('page_controls').hasChildNodes())
            var is_page_controls = $('page_controls').down("div").hasChildNodes();
            
        if ($('menu_container')) {
            Event.observe(window, 'scroll', function(event) {
                var menu = $('menu_container'), y_pos = window.scrollY;
                // take the full page height, remove the height of the menu, and offset by the padding above said menu, and the footer
                var bottom_pos = Menu.getMaxDocumentHeight() - menu.scrollHeight - $('footer').scrollHeight + 10;
                var header_height = document.body.scrollHeight - $("middlecolumn").scrollHeight - $('footer').scrollHeight;
                
                if (y_pos > header_height) {
                    if (y_pos <= bottom_pos) {
                        menu.setStyle({position: 'fixed', top: ''});
                        if (is_page_controls) {
                            $("page_controls").up("div").addClassName("hover").addClassName("shadow-box");
                            $("page-settings").setStyle({marginTop: '0'});
                        }
                    } else {
                        menu.setStyle({top: '-'+(y_pos - bottom_pos)+'px'});
                    }
                } else {
                    menu.setStyle({position: '', top: ''});
                    $("page_controls").up("div").removeClassName("hover").removeClassName("shadow-box")
                    $("page-settings").setStyle({marginTop: ''});
                }
                
            });
        }
        
        // register showing and hiding stuff for the profile page
        if (typeof table_names != 'undefined') {
            table_names.each(function (table_name) {
                
                for (var i = 0; i < ids[table_name].length; i++) {
                    var field_to_highlight = ids[table_name][i];
                    
                    hookEventsFor(field_to_highlight, table_name);
                
                    // When the person clicks down, see about removing the help if necessary
                    // Don't hide the box if the helpbox itself is clicked
                    Event.observe(document, 'mousedown', function(event) {
                        if ($$('.help-box').length) {
                            var el = Event.element(event);
                            var is_helpbox = (el.className == "help-box" ? true : false);
                            var has_helpbox_parent = (typeof el.up(".help-box") != "undefined" ? true : false);
                            
                            if (!is_helpbox && !has_helpbox_parent) {
                                hideHelpFor(field_to_highlight, table_name);
                            }
                        }
                    });
                }
          });
        }
        
        // Make sure the footer min-height position is set properly
        Menu.setFooterPosition();
        
        // and the notification box
        Menu.bounceNewBox("new_feature", "new_box");
        
        // If editorial content has images linking to themselves, remove the link
        $$(".contentSectionBody a img").each(function(element) {
            var elLink = element.up("a");
            if (element.src === elLink.href) {
                elLink.href="#";
                elLink.style.cursor="default";
            }
        });
    });
    
}



/**
 * These are some commands that will run even before the page
 * has completed loading. This is primarily meant to 
 * fetch the layout images, and register some events,
 * so we don't have blocky boxes suddenly becoming rounded, 
 * and aren't relying on the flaky onLoad inline event.
 */
Menu.preLoader = function ()
{
    // Reusable loading images stored in an array
    var image_prefix = "/images/";
    var img_arr = ["ajax-loading-balls.gif",
                   "corners/green_on_green_circle.gif",
                   "corners/white_on_grey_circle.gif",
                   "corners/white_on_green_circle.gif"];
    
    // load them up
    for (var i = img_arr.length - 1; i >= 0; i--) {
        var temp_image = new Image();
        temp_image.src = [image_prefix,img_arr[i]].join("");
    }

    // And initialize the page
    Menu.init();
    
}

/**
 * This function should be set to run after all ajax calls, to do any page
 * cleanup and other bits. Based on the structure of the response, it will
 * return true if the response 'looks' valid, and false if the response is
 * like a full page. Currently, this simply checks for the DOCTYPE string.
 */
Menu.postAjaxUpdate = function (transport)
{
    var response;
    if (typeof transport == 'undefined') {
        return true;
    }
    
    if (typeof transport.responseText != 'undefined') {
        response = transport.responseText;
    }
    
    // We got some response text, but it isn't a server error page (probably log in page)
    if (response && transport.status != 500) {
        // because we check required login and redirect elsewhere, make sure some other
        // page isn't seeping in.
        if (!DEBUG) {
            if (response.substr(0,10).search(/DOCTYPE/) > 0) {
            
                // Create a new container element with some text, and place it in 
                var message = new Element('div', {'class': 'status_problem'}).update("There was a problem loading your page. We apologize for this inconvenience.<br /> Please refresh this page in order to view the content correctly. (Error 6002)");
                $('middlecolumn').update().appendChild(message);
                return false;
            } else {
                // use the return value of this method to do special things you need 
                return true;
            }
        } else {
            return true;
        }
    } else {
        // This is likely some mal-formed error page which wasn't escaped, and just dumped in
        if (typeof console != 'undefined') {
            console.log("error page dumped in... check formatting!");
        }
        return false;
    }

}

/**
 * This function will adjust the footer on the page to sit properly
 * at the bottom. It will adjust for the tallest item, and be below
 * that. This changes the minimum height, so that the page can be larger if needed.
 *
 * This is accomplished by taking the full page height, and removing the height
 * of the footer, and it's position from the top. That is added to the current
 * height of the adjusted element to result in the appropriate footer height.
 * 
 * This returns a reference to the element that was actually adjusted.
 */
var IE_RESIZE_PREV_SIZE = 0;
var MARGIN_PADDING_OFFSET = 25;
Menu.setFooterPosition = function ()
{
    
    // Set the variable to adjust. It always is either middlecolumn or logged_off_middlecolumn
    if ($('middlecolumn'))
        elementToAdjust = 'middlecolumn';
    else 
        elementToAdjust = 'logged_off_middlecolumn';
        
    var footerobj = $('footer');
    var elemAdj = $(elementToAdjust);
    
    // objects for the height of the page
    var menuAdj = $('menu_container');
    var headerAdj = $('header_dos');
    
    var menuHeight = ((menuAdj) ? menuAdj.offsetHeight : 0);
    
    // IE fires many resize events for no reason at all. This checks if the
    // values are actually different and keeps it if so
    var biggestHeight = Math.max(menuHeight, elemAdj.offsetHeight);
    
    if (document.viewport.getHeight() != IE_RESIZE_PREV_SIZE && (document.viewport.getHeight()-footerobj.offsetHeight) > (menuHeight+headerAdj.offsetHeight)) {
        
        var newValue = document.viewport.getHeight() - footerobj.offsetHeight - footerobj.offsetTop;
        newValue += biggestHeight;
        
        // Removing values which make up the collection of vertical paddings
        // and margins in the base template, which comes to about 25 pixels
        newValue -= MARGIN_PADDING_OFFSET;
        
        new Effect.Morph(elementToAdjust, {
            duration: 0.1,
            style: "min-height: " + newValue + "px"
        });
        
        if (Menu.isIE() && Menu.isIE() < 7.0) {
            elemAdj.style.height = newValue + "px";
        }
        
        IE_RESIZE_PREV_SIZE = document.viewport.getHeight();
    }
    
    return elemAdj;
}

Menu.clearFooterPosition = function (elementName)
{
    
    $(elementName).setStyle({
      height: ""
    });
    
}

/**
 * Function for loading big loading images (for instance, when changing items on
 * zoom widget). This simply sets a class on the specified element instead of
 * creating an image resource.
 *
 * inTarget - where you are putting that new class
 *
 * This returns the image container element.
 */
Menu.createLoadingImg = function (inTarget)
{
    var tg = $(inTarget);
    // set the class for the target to be 'loading'
    tg.update().addClassName('loading');
    
    // Guarantee it enough height to show the image (about 100 pixels)
    if (tg.offsetHeight < 100) tg.style.height = "100px";
    return tg;
}

/**
 * Function for hiding any big loading images that have been created by the
 * createLoadingImg call. Also remove any special height given, letting the
 * element return to its natural height.
 *
 * inTarget - where you are removing that loading image
 *
 * This returns the element where the call was made, regardless of whether a loading
 * image was there.
 */
Menu.removeLoadingImg = function (inTarget)
{
    var tg = $(inTarget);
    tg.removeClassName('loading');
    tg.style.height = null;
    
    return tg;
}

/**
 * This function will create the styling necessary to dynamically generate a
 * regular box with rounded white corners.
 *
 * It puts the box (with the withId) in the named container)
 *
 * Like most prototype-y things, it returns the extended element that was created.
 */
Menu.createWhiteBox = function (withId, inNamedContainer) {
   /** It should look like the following
    * <div class="white box" id=withId>
    * <div class="topWhiteCorner">
    *    <div>&nbsp;</div>
    * </div>
    * <div class="box" id=withId_content><!-- content here --></div>
    * <div class="bottomWhiteCorner">
    *    <div>&nbsp;</div>
    * </div>
    * </div>
    *
    * http://code.google.com/p/dombuilder/
    */
    
    var space = new Element("div").update("&nbsp;");
    var space2= new Element("div").update("&nbsp;"); 
    
    // top border
    var topBorder = new Element("div", {"class": "topWhiteCorner"});
    
    // bottom border
    var bottomBorder = new Element("div", {"class": "bottomWhiteCorner"});
    
    var contentSection = new Element("div", {"class" : "white box", "id" : withId+"_content"});
    
    var container = new Element("div", {"class" : "white box", "id": withId});
    
    // and stitch them together
    container.appendChild(topBorder);
    container.appendChild(contentSection);
    container.appendChild(bottomBorder);
    
    // and the spaces where they belong
    topBorder.appendChild(space2);
    bottomBorder.appendChild(space);
    
    // and stick the whole bit where it belongs
    //$(inNamedContainer).innerHTML = "";
    $(inNamedContainer).appendChild(container);
    
    return container;
}

/**
 * Return the Internet Explorer Version, or zero (if it isn't IE)
 */
Menu.isIE = function()
{
    
    //if (typeof(console) != 'undefined') {
    //    console.log("Consider using Prototype's Browser method (Prototype.Browser)");
    //}
    
    if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)) { //test for MSIE x.x;
        
        var ieversion = new Number(RegExp.$1) // capture x.x portion and store as a number
        return parseFloat(ieversion);
        
    } else {
        
        return 0;
        
    }
    
}

/**
 * This is a wrapper for opening popup windows for help pages, which can include
 * both the page name, and any internal page anchors.
 *
 *  @param contentPage {string} wiki-type page to open (like Keyword_Help[#Page_Anchor])
 *  @param dimensions {string } [optional] window dimensions (like width=x,height=y)
 * Returns nothing
 */
Menu.openHelp = function(contentPage, dimensions)
{
    var dimen = ((typeof dimensions != 'undefined') ? dimensions : "width=580,height=340");
    window.open('/pages/popup/'+contentPage, 'keyword_help','status=0, toolbar=0,'+dimen+',scrollbars=1,location=0,resizeable=0');
}

/**
 * This sets a cookie so that new-feature reminders are dismissed
 * permanently (not just hidden, but no longer sent over)
 *
 * Returns nothing
 */
Menu.killNewFlag = function(targetBoxElement) {
    new Ajax.Request("/homepage/stop_new_search_reminder", {
        method: 'GET',
        asynchronous: true
    });
    
    $(targetBoxElement).fade({duration: 0.3});
}

/**
 * We'll be labeling new content occasionally. This is a javascript method to handle
 * showing those.
 *
 * Returns nothing
 */
Menu.bounceNewBox = function(activatorElementName, targetBoxElement, shouldLinger) {
    var newFeature = $(activatorElementName);
    var boxToMove = $(targetBoxElement);
    var lingering = ((typeof shouldLinger !== 'undefined') ? shouldLinger : false);
    
    if (newFeature && boxToMove) {
        // Use Tween() to make the box slide a bit when the field is hovered over.
        if (!lingering) {
            newFeature.observe("mouseover", function(event) {
                new Effect.Tween(boxToMove, parseFloat(boxToMove.style.top.substr(0,2)), 36, {duration: 0.25}, function(p) {boxToMove.style.top = p+"px";});
                new Effect.Appear(boxToMove, {duration: 0.25, afterFinish: function(event) {
                    $$('html')[0].observe("mouseover", function(event) {
                        new Effect.Tween(boxToMove, parseFloat(boxToMove.style.top.substr(0,2)), 27, {duration: 0.25}, function(p) {boxToMove.style.top = p+"px";});
                        new Effect.Fade(boxToMove, {duration: 0.25, afterFinish: function(event) {
                            $$('html')[0].stopObserving("mouseover");
                        }});
                    });
                }});
            });
        } else {
            new Effect.Tween(boxToMove, parseFloat(boxToMove.style.top.substr(0,2)), 36, {duration: 0.25}, function(p) {boxToMove.style.top = p+"px";});
            new Effect.Appear(boxToMove, {duration: 0.25});
        }
    }
}

/**
 * use the Posts' IDs to get the location of the thumbnail image, then place
 * it in the referenced element 'src' attribute (skip elements that aren't IMG)
 *
 * Returns boolean whether the element was modified or not
 */
Menu.setThumbnail = function (element)
{
    var el = $(element.id);
    if (el.tagName.toLowerCase() === "img" && el.src !== "/pages/id/"+el.id+".jpg") {
        el.src = "/pages/id/"+el.id+".jpg";
        return true;
    }
    return false;
}

/**
 * Set the email alert, optionally specifiying a category filter to use along
 * with the search text. Alert the user after the interation.
 *
 * Returns nothing
 *
*/
Menu.setEmailAlert = function (event, search_text, category_filter)
{
    Menu.bounceNewBox("alert_set", "alert_box", true);
    
    var params = { },
        url = "/email_alerts/add";
    
    // Put in all the values for the new search alert
    params["q"] = search_text;
    
    if (category_filter != null && category_filter != "") {
        params["category"] = category_filter;
        url += "-content";
    }
    
    new Ajax.Request(url, {
        method: 'POST',
        parameters: params,
        asynchronous: true,
        onSuccess: function(transport) {
            var alertObj = $("alert_set");
            alertObj.stopObserving("click");
            alertObj.removeAttribute("onclick");
            alertObj.observe("click", function(event) {
                Menu.unsetEmailAlert(event, transport.responseText);
            }).update("Unset Alert");
        },
        onFailure: function(transport) {
            if ($("alertbox"))
                $("alertbox").innerHTML = transport.responseText;
            else
                Event.element(event).innerHTML = transport.responseText;
        }
    });
    
}

Menu.unsetEmailAlert = function (event, alertId)
{
    var params = { },
        url = "/email_alerts/delete";
        
    params["id"] = alertId;
    
    new Ajax.Request(url, {
        method: 'POST',
        parameters: params,
        asynchronous: true,
        onSuccess: function(transport) {
            $("alert_set").stopObserving("click");
            $("alert_set").observe("click", function(event) {
                // these are global variables
                if (typeof category_filter != "undefined") {
                    Menu.setEmailAlert(event, search_text, category_filter);
                } else {
                    Menu.setEmailAlert(event, search_text, "");
                }
            }).update("Set Email Alert");
        },
        onFailure: function(transport) {
            if ($("alertbox"))
                $("alertbox").innerHTML = transport.responseText;
            else
                Event.element(event).innerHTML = transport.responseText;
        }
    });
}

/**
 * Check to see if the current category is set as a content alert in the system
 * for the given user.
 */
Menu.isAlertSet = function (event, category_filter)
{
    var params = { },
        url = "/email_alerts/is_content_alert_set";
    
    params["category_filter"] = category_filter;
    params["ms"] = Date.UTC();

    new Ajax.Request(url, {
        method: 'GET',
        parameters: params,
        asynchronous: true,
        onSuccess: function(transport) {
            var result = transport.responseText.evalJSON(true);
            if(result) {
                $("alert_set").stopObserving("click");
                $("alert_set").observe("click", function(event) {
                    Menu.unsetEmailAlert(event, result);
                }).update("Unset Alert");
            } else {
                $("alert_set").stopObserving("click");
                $("alert_set").observe("click", function(event) {
                    Menu.setEmailAlert(event, "", category_filter);
                }).update("Set Email Alert");
            }
        },
        onFailure: function(transport) {
            alert("Miscellaneous Failure...");
        }
    });
}

/**
 * Determine the name of the subdomain where the site is running.
 */
Menu.getSubDomain = function () {
    return window.location.host.split(".")[0];
}

/**
 * Get the document height based on the related parameters that can return
 * that value.
 *
 * since FF6.0 broke document.height value.
 *
 * return an integer value for the height
 */
Menu.getMaxDocumentHeight = function() {
    var d = document;
    return Math.max(
        Math.max(d.body.scrollHeight, d.documentElement.scrollHeight),
        Math.max(d.body.offsetHeight, d.documentElement.offsetHeight),
        Math.max(d.body.clientHeight, d.documentElement.clientHeight)
    );
}

/** 
 * close the "contact [analyst] box on the screen
 */
Menu.closeContactForm = function(event, popup_name) {
    var contact_box = $(popup_name);
    
    contact_box.fade({duration: 0.25, afterFinish: function(event) {
        var parent = contact_box.parentNode;
        parent.removeChild(contact_box);
    }});
    
    Event.stopObserving(window, 'click');
}

/** 
 * Generate the contact form box as an inpage popup (via iframe)
 * target link must be inside a H6 tag for referencing the position. 
 * 
 * returns the ID of the popup created. 
 */
Menu.showContactForm = function(event, content_id, target_link)
{

    var pos = (Event.pointerY(event) > (document.height/2) ? "lo" : "hi");
    var hilo = {
        "hi" : "25px",
        "lo" : "-225px"
    };
    
    var popupId = target_link+"_popup";
    
    var v = new Element("div", {id: popupId}),
        iframe = new Element("iframe"),
        target = $(target_link).up("h6"),
        closeLink = new Element("div").setStyle({
            textAlign: 'right',
            border: '0',
            position: 'absolute',
            top: '0.2em',
            right: '1em'
        }).update("<a href='javascript:void(0);' onclick='return false'>[Close]</a>");
    
    // set up container
    v.setStyle({
        position: 'absolute',
        display: 'none',
        height: '210px',
        width: '450px',
        display: 'none',
        top: hilo[pos],
        border: '1px solid #87C544',
        left: '15px',
        backgroundColor: 'white'
    }).addClassName("shadow-box").addClassName("contact-box");
    
    var arrowBox = new Element("div", {'class': pos + " arrow"}).setStyle({
        backgroundPosition: '-140px 0%',
        position: 'absolute',
        left: '0',
        width: '100%'
    }).update("");
    
    // Set up internal frame
    iframe.setAttribute("src", "/pages/contact_analyst/page="+content_id);
    iframe.setStyle({
        overflow: 'hidden',
        border: '0',
        margin: '0',
        padding: '0',
        width: '100%',
        height: '100%'
    });
    
    target.setStyle({
        position: 'relative'
    }).appendChild(v);
    
    v.appear({duration: 0.25, afterFinish: function(event) {
        if (pos == 'hi') {
            v.appendChild(arrowBox);
            v.appendChild(closeLink);
            v.appendChild(iframe);
        } else {
            v.appendChild(closeLink);
            v.appendChild(iframe);
            v.appendChild(arrowBox);
        }
    }});

    return popupId; 
}

