/***
Filename:		base.js
Author:			James Condliffe
Date:			28/06/2007
Description:	Base Javascript for Ramsden International
***/


/***
Gets the user id from its location in the markup
***/
function getUserID()
{
    if($("userdetails"))
    {
        return $("userdetails").readAttribute("userid");
    }
    
    return null;
}

/***
Gets the webservice URI from its location in the markup
***/
function getWebserviceURI()
{
    if($("nisaint"))
    {
        //return 'not the url';
        return $("nisaint").readAttribute("webservice");
    }
    
    return null;
}


/* Open external links in new window / tab */
(function(){

    Event.observe(document,"dom:loaded",init);
    
    var baseHref;

    function init()
    {
	    // Grab our current base hostname	    
	    var regexp = /(https?:\/\/)([^\/]+)/i;
	    matches = regexp.exec(window.location);	
	    baseHref = matches[2];

	    // Check each link with a href attribute
	    $$("a[href]").each(checkLink);
    }
    
    function checkLink(anchor)
    {
	    var href = anchor.readAttribute("href");

	    if ( (href.indexOf(baseHref) < 0 && href.indexOf("http://") > -1 && anchor.readAttribute("rel") != "noexternal") || anchor.readAttribute("rel") == "external" || href.indexOf(".pdf") > -1) // it's an external link
	    {
	        anchor.observe("click", newWin);
	    }
    }
    
    function newWin(e)
    {
        window.open(this.getAttribute('href'));        
        Event.stop(e);
    }

})();

/* Rollover menus for less CSS compliant browsers */
(function(){

    //Event.observe(window,"load",init);

    function init()
    {        
	    var primarynav_options = $("primarynav").getElementsByTagName("li");
    	
	    // Loop through each option in the primary navigation
	    for (var i=0; i < primarynav_options.length; i++)
	    {
		    var option = primarynav_options[i];
		    var secondarynav = option.getElementsByTagName("ul");

		    if(secondarynav.length > 0)
		    {
			    secondarynav[0].className = "closed";
    			
			    option.onmouseover = openPopupMenu;
			    option.onmouseout = closePopupMenu;
		    }
	    }
    }

    function openPopupMenu()
    {
	    var submenu = this.getElementsByTagName("ul")[0];
	    message(submenu.id);
    	
    }

    function closePopupMenu()
    {    
        var submenu = this.getElementsByTagName("ul")[0];
	    submenu.className = "closed";
    }

})();



/* 'Hovering' labels over form fields */
(function(){

    Event.observe(document,"dom:loaded",init);

    function init() 
    {
      if (!document.getElementById) return;      

      var labels, id, field;

      // Set focus and blur handlers to hide and show labels with 'overlabel' class names.
      labels = document.getElementsByTagName('label');

      for (var i = 0; i < labels.length; i++) {

        if (labels[i].className == 'overlabel') {

          // Skip labels that do not have a named association with another field.
          id = labels[i].htmlFor || labels[i].getAttribute('for');
          if (!id || !(field = document.getElementById(id))) {
            continue;
          } 

          // Change the applied class to hover the label over the form field.
          labels[i].className = 'overlabel-apply';

          // Hide any fields having an initial value.
          if (field.value !== '') {
            hideLabel(field.getAttribute('id'), true);
          }

          // Set handlers to show and hide labels.
          field.onfocus = function () {hideLabel(this.getAttribute('id'), true);};
          field.onchange = function () {hideLabel(this.getAttribute('id'), true);};
          
          // This event is fired by IE when, among other things, the field is autocompleted.
          // If autocomplete is used, we want to hide the label
          field.onpropertychange = 
            function () 
            {
                if(this.value.length > 0)
                {
                    hideLabel(this.getAttribute('id'), true);
                }
            };      
          
          field.onblur = function () {
            if (this.value === '') {
              hideLabel(this.getAttribute('id'), false);
            }
          };

          // Handle clicks to label elements (for Safari).
          labels[i].onclick = function () {
            var id, field;
            id = this.getAttribute('for');
            if (id && (field = document.getElementById(id))) {
              field.focus();
            }
          };

        }
      }
    };

    function hideLabel (field_id, hide) {
      var field_for;
      var labels = document.getElementsByTagName('label');
      for (var i = 0; i < labels.length; i++) {
        field_for = labels[i].htmlFor || labels[i].getAttribute('for');
        if (field_for == field_id) 
	    {
		    //labels[i].style.textIndent = (hide) ? '-1000px' : '0px';
		    labels[i].style.marginLeft = (hide) ? "-1000px" : "";
		    return true;
        }
      }
    }

})();




/* Expanding menus */
(function(){

    Event.observe(document,"dom:loaded",init);

    var COLLAPSE_IMAGE_URL = "images/collapse.gif";
    var EXPAND_IMAGE_URL = "images/expand.gif";
    var LANGUAGE_COLLAPSE;
    var LANGUAGE_EXPAND;


    function init()
    {
        // Get the menu(s)
        var menus = $$("ul.subnav");
        
        // Check that there are > 0 menus and that they require expanding functionality
        if(menus.length > 0 && $$("ul.subnav ul").length > 0)
        {
            for(var i = 0; i < menus.length; i++)
            {
                var menu = menus[i];
                
                // Get all menu children
                var menuChildren = menu.getElementsBySelector("li");
                
                // Acquire language from markup
                LANGUAGE_COLLAPSE = menu.readAttribute("collapse");
                LANGUAGE_EXPAND = menu.readAttribute("expand");
                
                // Set up all our nodes
                menuChildren.each(setupNode);
                
                // Reduce indent on top level li elements
                var li = $$("ul.subnav>li");
                li.each( function(s){s.setStyle({marginLeft: 0});} );
            }
        }    
    }

    /***
    Accepts a LI element, if it contains a sub-list, collapses it and appends a toggle widget
    ***/
    function setupNode(node)
    {    
        if(node.getElementsBySelector("ul").length > 0)
        {    
            // Get the submenu
            var nodeMenu = node.getElementsBySelector("ul")[0];
            
            // Create the button that allows the user to toggle
            var toggleWidget = new Element("img", { className: "togglewidget" });
            toggleWidget.observe("click", toggleNode);        
            
            if(nodeMenu.readAttribute("expanded") == "true")
            {
                setWidget(toggleWidget,"collapse");
                node.addClassName("expanded");
            }
            else
            {
                nodeMenu.hide();
                setWidget(toggleWidget,"expand");
            }
            
            // Inset our button into the document
            node.insertBefore(toggleWidget, node.firstChild);
        }
        /*else if(node.readAttribute("childdataavailable") == "false") // fake expansion button
        {
            // Create the button that allows the user to toggle
            var toggleWidget = document.createElement("img");
            Element.extend(toggleWidget);
            toggleWidget.addClassName("togglewidget");
            setWidget(toggleWidget,"expand");

            // Inset our button into the document
            var x = node.firstChild.innerHTML;
            node.firstChild.innerHTML = "";
            node.firstChild.appendChild(toggleWidget);
            node.firstChild.innerHTML = node.firstChild.innerHTML + x;
        }*/
        else
        {        
            // Mimic 'expand' widget with additional padding
            node.setStyle({paddingLeft: "17px"});
        }
    }

    /***
    With reference to the clicked toggling widget, hides or shows the associated submenu
    and swaps the toggle widget's image as required
    ***/
    function toggleNode()
    {
        var button = this;
        var node = this.parentNode;
        var nodeChild = node.getElementsBySelector("ul")[0];
        
        nodeChild.toggle();
        
        // Set the toggle widget
        if(nodeChild.visible())
        {
            setWidget(button,"collapse");
            node.addClassName("expanded");
        }
        else
        {
            setWidget(button,"expand");
            node.removeClassName("expanded");
        }
    }

    /***
    Sets up the command widget.
    For example if 'state' is specified as 'expand' the button is displayed as a + with alt text of "expand"
    ***/
    function setWidget(widget, state)
    {
        if(state == "expand")
        {
            widget.src = EXPAND_IMAGE_URL;
            widget.setAttribute("title",LANGUAGE_EXPAND);
            widget.setAttribute("alt",LANGUAGE_EXPAND);
        }
        else
        {
            widget.src = COLLAPSE_IMAGE_URL;
            widget.setAttribute("title",LANGUAGE_COLLAPSE);
            widget.setAttribute("alt",LANGUAGE_COLLAPSE);
        }
    }

})();


/* Periods dropdown auto submit */
(function(){

    Event.observe(document,"dom:loaded",init);

    function init()
    {
        var periodsSelect = $$("form#periods select#period").first();
        
        if(periodsSelect)
        {
            var periodsSubmit = $$("form#periods input[type='submit']").first();
                    
            periodsSubmit.hide();
            periodsSelect.observe("change",function(){this.up("form").submit();});
            
        }
    }

})();


/* Personalised list */
(function(){

    Event.observe(document,"dom:loaded",init);
    
    var actionTextAdd, actionTextRemove;

    function init()
    {
        // Get the product list
        var products = $$("ul.productcategories ul.products>li");
        
        // Functionality only required if user is logged in and the webservice is available
        if(getUserID() == null || getWebserviceURI() == null || products.length < 1)
        {
            return;
        }
        
        // Get appropriate action text
        actionTextAdd = $$("ul.productcategories")[0].getAttribute("addtext");
        actionTextRemove = $$("ul.productcategories")[0].getAttribute("removetext");
                
        // Set up the widget on each item
        products.each(
            function(node)
            {
                if(!node.hasClassName("deleted"))
                {
                    var widget = node.getElementsBySelector("a.personallisttoggle");
                    
                    if(widget.length > 0)
                    {
                        widget = widget[0];
                        widget.observe("click", togglePersonalisedList);
                    }                    
                }                
            }
        );
    }

    function togglePersonalisedList(e)
    {        
        // Collate data required to perform our request
        var widget = this;
        var widgetimage = widget.down("img");
        var widgetImageSrc = widgetimage.readAttribute("src");
        var item = widget.up("li.product");   
        var productid = item.readAttribute("productid");
        var userid = getUserID();    
        var inlist = (item.readAttribute("inpersonallist") == "1") // current list status, convert to boolean
        var url = getWebserviceURI();        
        
        // Local variables
        var actionurl;
        var newimagesrc;
        var newstatus;
        var widgeteventhandler;
        var newActionText;
        
        // Set the request url depending on current status
        if(inlist)
        {
            actionurl = url + "/RemoveProductFromPersonalList";
            newimagesrc = "images/add.gif";
            newstatus = 0;
            newActionText = actionTextAdd;
        }
        else
        {
            actionurl = url + "/AddProductToPersonalList";
            newimagesrc = "images/remove.gif";
            newstatus = 1;
            newActionText = actionTextRemove;
        }
            
        // Create our AJAX request
        new Ajax.Request(actionurl, {
            method: "post",
            parameters: {ProductCode: productid, iUserID: userid},
            
            onCreate:
            function()
            {
                // Set loading graphic
                widgetimage.src = "images/loading.gif";
                //widget.addClass("inprogress");
            },
      
            onSuccess:
            function(transport) 
            {
                // Set new function graphic
                widgetimage.src = newimagesrc;
                widgetimage.style.border = "";
                widgetimage.writeAttribute("alt",newActionText);
                widget.writeAttribute("title",newActionText);                
                
                // Update status of item
                item.writeAttribute("inpersonallist", newstatus);
            },
            
            onFailure:
            function(transport)
            {
                alert("Personalised list toggle failed with response \"" + transport.statusText + "\".");
                //window.showError(, false, 4);
                widgetimage.writeAttribute("src", widgetImageSrc);
            }
        });
        
        Event.stop(e);
    }

})();

/* Error notification */
(function(){

    Event.observe(document,"dom:loaded",init);
        
    function init()
    {       
        window.showError = showErrorNotification;
        window.hideError = fadeErrorNotification;
    }
    
    function showErrorNotification(intErrType, blnPersist, intShowFor){
        
        var errNum;
        //a container to hold all errors
        if(!$('allErrs'))
        {
            var ecDiv = document.createElement('div');
            Element.extend(ecDiv);
            ecDiv.setAttribute('id','allErrs');
            //append the container to the main body div
            $('nisaint').appendChild(ecDiv);
            errNum = 0;
            
        }
        
        //check if the error div has already been built.
        if(true)    //!$('errMsgDiv'))
        {
            var eDiv = document.createElement('div');
            Element.extend(eDiv);
            var innerMsg = document.createElement('p');
            Element.extend(innerMsg);
            innerMsg.innerHTML = 'An unspecified error occured.<br/>That\'s not good...';
            innerMsg.style.margin = '5px';
            eDiv.appendChild(innerMsg);
            
            $('allErrs').appendChild(eDiv);
            console.log(eDiv);
            errNum = ($('allErrs').childElements().length) - 1;
            console.log('total active errors: '+errNum);
        }
        
        //the error is prepared - show to the user
        if(intErrType == 1)
        {
            $('allErrs').childElements()[errNum].className = 'genErr';
        }
        
        if(errNum > 0)
        {
            $('allErrs').childElements()[errNum].style.top = (errNum * 60+10)+"px";
            console.log('top: '+$('allErrs').childElements()[errNum].style.top);
        }
        $('allErrs').childElements()[errNum].show();
        Element.setOpacity($('allErrs').childElements()[errNum],1);
        
        if(!blnPersist) setTimeout(hideError,(intShowFor*1000), $('allErrs').childElements()[errNum]);     
         
    }
    
    function fadeErrorNotification(errObjRef){
        var speed = 10; //speed for each frame
        var timer = 0;
	    var opacStart = 100; // starting opacity
	    var opacEnd = 0; // ending opacity
	    
	    for(i = opacStart; i >= opacEnd; i--) 
        {
            //console.log(theError);
	        //setTimeout("Element.setOpacity(theError," + (i/100) + ");", (timer * speed));
	        setTimeout(timedOpacity, (timer * speed), errObjRef, (i/100));
	        timer++;
	        if(timer > 100){
	            console.log(timer);
	            setTimeout(timedRemove, (timer * speed), errObjRef);
	        }
        }
    }
    
    function timedOpacity(obj,opac){
        Element.setOpacity(obj,opac);
    }
    
    function timedRemove(obj){
        obj.remove();
    }
 
    
})();


/* FAQ expanders */
(function(){

    Event.observe(document,"dom:loaded",init);
        
    function init()
    {        
        var faqcontainer = $("faqcontainer");
        
        if(!faqcontainer)
        {
            return;
        }
        
        var questions = faqcontainer.select("h5");
        var answers = faqcontainer.select("div.answer");
        var toggle = $("toggleall");
        
        answers.invoke("hide");
        
        questions.each(function(o)
            {
                o.observe("click", toggleAnswer);
                o.addClassName("question");
            });
        
        if(!toggle)
        {
            return;
        }
        
        toggle.addClassName("enabled");
        toggle.observe("click", function()
            {
                answers.invoke("toggle");
            });
    }
    
    function toggleAnswer()
    {
        $(this.readAttribute("rel")).toggle();
    }
    
})();

/* Add the dropdown functionality for IE 6 */
(function(){
    
    if(Prototype.Browser.IE && (navigator.appVersion.indexOf('MSIE 6') > 0)) //ie 6 test
    {
        Event.observe(document,"dom:loaded",init);
    }
    
    function init()
    {
        var thenav = $$("ul#primarynav > li");
        if(thenav)
        {
            for(var i=0; i < thenav.length; i++)
            {
                addEvent(thenav[i], "mouseover", hoverNav);
                addEvent(thenav[i], "mouseout", hideNav);
            }            
        }
    }
    
    function hoverNav(e)
    {
        this.childNodes[1].style.display = 'block';
    }
    
    function hideNav(e)
    {
        this.childNodes[1].style.display = 'none';
    }

})();

/* Add multiple event handlers to an object */
function addEvent( obj, type, fn )
{
	if (obj.addEventListener)
		obj.addEventListener( type, fn, false );
	else if (obj.attachEvent)
	{
		obj["e"+type+fn] = fn;
		obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
		obj.attachEvent( "on"+type, obj[type+fn] );
	}
}