﻿YAHOO.namespace("oralb.Tools");
var CCONSUMER = 0;
  
(function () { // self invoking function
  //enum
  YAHOO.oralb.Tools.MENU_LAYOUT = { _HORIZONTAL : "horizontal", _VERTICAL: "vertical" }

  YAHOO.oralb.Tools.EVENT_TYPES = {
    clickEvent: "click",
    mouseDownEvent: "mousedown",
    mouseUpEvent: "mouseup",
    mouseOverEvent: "mouseover",
    mouseOutEvent: "mouseout",
    keyDownEvent: "keydown",
    keyUpEvent: "keyup",
    keyPressEvent: "keypress",
    focusEvent: YAHOO.env.ua.ie ? "focusin" : "focus",
    blurEvent: YAHOO.env.ua.ie ? "focusout" : "blur"
  };

  /**
  * MenuManager is a utility
  *
  * @namespace YAHOO.oralb.Tools
  * @class MenuManager
  * @constructor
  * @param {Object - HTML Element} alignToElement The html Element or string representing a HTML element that we wish to append our menus too.
  */
  YAHOO.oralb.Tools.MenuManager = function(alignToElement){
    _menuContainerCollection = new Array();
    _currentMenuContainerId = 0;
    _alignToElement = YAHOO.lang.isObject(alignToElement) ? alighToElement : YAHOO.util.Dom.get(alignToElement);
    layout = YAHOO.oralb.Tools.MENU_LAYOUT._HORIZONTAL;
  };   
  
  YAHOO.oralb.Tools.MenuManager.prototype = {
    menuItemBlurEvent : new YAHOO.util.CustomEvent("menuItemBlurEvent", this),
    menuItemFocusEvent : new YAHOO.util.CustomEvent("menuItemFocusEvent", this),
    menuItemClickEvent : new YAHOO.util.CustomEvent("menuItemClickEvent", this),
    menuItemKeyPressEvent : new YAHOO.util.CustomEvent("menuItemKeyPressEvent", this),
    showMenuComplete : new YAHOO.util.CustomEvent("showMenuComplete", this),
    
    /**
    * 
    * @method addMenuContainer
    * @param {String} menuKey Key to associate with this MenuContainer
    * @param {Object} oCfg The
    */
    addMenuContainer : function(menuKey, parentMenuKey, oCfg){
      _menuContainerCollection.push({key: menuKey, parentKey:parentMenuKey, value: new YAHOO.oralb.Tools.MenuContainer(_alignToElement, YAHOO.lang.merge({id: menuKey}, oCfg))});
    },
    
    /**
    * gets a MenuContainer by key 
    * @method getMenuContainer
    * @param {String} key Key to associate with this MenuContainer
    * @return {Object} if found returns a MenuContainer object
    */
    getMenuContainer : function(key){
      for(var c in _menuContainerCollection){ 
        if(_menuContainerCollection[c].key == key)
          return _menuContainerCollection[c].value;
      }
    }, 
    
    // shows a menu item based on a parent id match
    // animate obj pass in
    showMenuFromParent : function(menuItemId, menuItemMenuId){
      var item = 0, menuId = null;

        // find matching container
        while(menuId==null&&item<_menuContainerCollection.length){
          menuId=_menuContainerCollection[item].value.getChildMenuId(menuItemId, menuItemMenuId);
          item++;
        }

        if(menuId!=null){
          this.showMenuFromId(menuId[0], menuId[1]);
          return true;
        }else {
          return false;
        }
    },
    
    clearChildMenuContainers : function(menuContainerId){
      // loop through each child menu container and clear its content.
      var menuContainer = this.getChildMenuContainer(menuContainerId);

      while(menuContainer!=null){
        // remove any child nodes
        menuContainer.hideMenuContainer();
        menuContainer = this.getChildMenuContainer(menuContainer.getId());
      }
    },
    
    getChildMenuContainer : function(menuContainerId){
      for(var item in _menuContainerCollection){ 
        if(_menuContainerCollection[item].parentKey == menuContainerId){ // only check
          return _menuContainerCollection[item].value;
        }
      }
    },
    
    // shows a menu item based on a id match
    // animate obj pass in
    showMenuFromId : function(containerId, menuId){
      var found = false;
      for(var item in _menuContainerCollection){ 
        if(_menuContainerCollection[item].key == containerId){
          // find our menu based on id
          _menuContainerCollection[item].value.showMenu(menuId);
          this.showMenuComplete.fire({menuKey: containerId, menuId:menuId}); // fire off complete event
          found = true;
        }
      }
      return found;
    },
    
    getMenuItems: function(menuKey, menuId){
      var menuItems = null;
      for(var item in _menuContainerCollection){ 
        if(_menuContainerCollection[item].key == menuKey){
          // find our menu based on id
          menuItems = _menuContainerCollection[item].value.getSiblingMenuItems(menuId);
          break;
        }
      }
      return menuItems;
    },
    
    getMenuContainersCount : function(){
      return _menuContainerCollection.length;
    },
       
    removeMenuContainer : function(containerIdId){
      var arrayPosition = -1;
      
      for(var item in this._menuContainerCollection){ 
        if(_menuContainerCollection[item].key == containerId)
          arrayPosition = item;
      }
     
      if(arrayPosition!=-1) { _menuContainerCollection = _menuContainerCollection.splice(arrayPosition,1); return true;
      } else
        return false;
    }
  }
  
  YAHOO.oralb.Tools.MenuContainer = function(renderToNode, oCfg){ // constructor
    // private member properties
    var _menuCollectionId = 0,
      _menuCollection = new Array(),
      _config = oCfg || {},
      _id = _config.id; 

    // build MenuContainer
    var _menuContainerDiv = createDiv({id:"ctr" + _id, cssClass: _config.cssClass});
    var _headerDiv = createDiv({id:"ctr" + _id + "_hd", cssClass: _config.headerCssClass, innerHtml: _config.title});
    var _bodyDiv = createDiv({id:"ctr" + _id + "_bd",  cssClass: _config.bodyCssClass});
    _menuContainerDiv.appendChild(_headerDiv);
    _menuContainerDiv.appendChild(_bodyDiv);

    try{
      renderToNode.appendChild(_menuContainerDiv);
    } catch (e) { 
      throw("Error: in MenuContainer constructor" + e);
    }
    // end build MenuContainer
         
    // public methods
    this.addMenu = function(parentMenuItemId, menuItemsCollection){  
       // create a new menu and add to collection.
      var thisId = _menuCollectionId;
      _menuCollection.push({id: _menuCollectionId, containerId: _id, parentId: parentMenuItemId, value:new YAHOO.oralb.Tools.Menu(_menuCollectionId, _id, menuItemsCollection)});
      _menuCollectionId++;
      return _menuCollection[thisId].value;
    };
    
    this.getChildMenuId = function(menuItemParentId, menuItemMenuId){
      var menuId = null;
      for(var item in _menuCollection){
        if(_menuCollection[item].parentId!=null){
          if(menuItemParentId[0] == _menuCollection[item].parentId[0] && menuItemParentId[1] == _menuCollection[item].parentId[1] && menuItemMenuId == _menuCollection[item].parentId[2]){ //_menuCollection[item].value.getId()          
              menuId = [_menuCollection[item].containerId, _menuCollection[item].id];
              break;
          }
        }
      }
      return menuId;
    };
            
    // get each menu item and append to _bd div element
    this.showMenu = function(id){
      //var bodyDivElement = YAHOO.util.Dom.get(bodyDiv)
      for(var item in _menuCollection){
        if(id==_menuCollection[item].id){
          //found our menu item 
          var menu = _menuCollection[item].value.getMenuItemCollection();
          var oldElement = _bodyDiv.firstChild;
          if(oldElement)
            _bodyDiv.removeChild(oldElement);
                    
          var element = document.createElement("ul");
          var fadeInArr = new Array();
          
          for(var mItem in menu){
              YAHOO.util.Dom.setStyle(menu[mItem].htmlElement, "opacity", "0");
              element.appendChild(menu[mItem].htmlElement);
              fadeInArr.push(new YAHOO.util.Anim(menu[mItem].htmlElement, { opacity: { to: 1 } }, .005));
          }

          for(var i=0; i<fadeInArr.length-1;i++){
            fadeInArr[i].onComplete.subscribe(function(type, args, me){me.arr[me.count].animate();}, {arr: fadeInArr, count: i+1});
          }
          
          if(fadeInArr.length>0)
            fadeInArr[0].animate();
          
          _bodyDiv.appendChild(element);
        }
      }
    };
    
    // hide the menu container based on the id passed
    this.hideMenuContainer = function(){
      var oldElement = _bodyDiv.firstChild;
      if(oldElement)
        _bodyDiv.removeChild(oldElement);        
    };
    
    this.getSiblingMenuItems = function(id){
      var returnArr = null;
      for(var item in _menuCollection){
        if(id==_menuCollection[item].id){
          //found our menu item 
          var menu = _menuCollection[item].value.getMenuItemCollection();
          returnArr = new Array();
          for(var mItem in menu){
            returnArr.push(menu[mItem]);
          }
        }
      }
      
      return returnArr;
    };
    
    // getters / setters
    this.getId = function(){ return _id; };
  };
  
  YAHOO.oralb.Tools.Menu = function(id, containerId, itemsCollectionArray){ // constructor
    var _menuItemCollection = new Array(), // add ability to assign collection directly or through constructor
      _menuItemCollectionCount = 0,
      _id = id,
      _containerId = containerId;
            
    //public methods
    this.addMenuItem = function(oCfg){ 
      var _config = oCfg || {},
        returnCount = _menuItemCollectionCount;

      if(!_config.title)
        throw("ArgumentNullException: Menu.addMenuItem");

      _menuItemCollection.push(new YAHOO.oralb.Tools.MenuItem(YAHOO.lang.merge({id:[_containerId, _menuItemCollectionCount], parentMenuId: _id}, _config)));
      _menuItemCollectionCount++;
      return returnCount;
    }
    
    this.getMenuItemCollection = function(){
      return _menuItemCollection;
    };
    
    
    // constructor
    if(itemsCollectionArray){
      for(var i in itemsCollectionArray){
         this.addMenuItem(itemsCollectionArray[i]);
      }
    }
    
    this.getId = function(){return _id};
  };
    
    
  // oCfg = {url:, title:, active:, bgColorActive:, bgColorIdle:}
  YAHOO.oralb.Tools.MenuItem = function(oCfg){ // constructor
    var _config = oCfg || {};
    
    if(!_config.title||!_config.id)
      throw("ArgumentNullException: in Menu constructor");
    this._id = _config.id;
	this.mode = _config.mode;
    this.parentMenuId = _config.parentMenuId;
    this.domId = this._id.join("_")+"_" + this.parentMenuId + "_menuItem";
    this.url = _config.url;
    this.title = _config.title;
    this.active = _config.active || false;
    this.cssClass = _config.cssClass;
    this.tabindex = _config.tabindex || null;
    this.htmlElement = createHtmlElement({id:this.domId, p:this._id, url:this.url, title:this.title, active: this.active, cssClass: this.cssClass, tabindex: this.tabindex})
    this.init();
    };
    
    YAHOO.lang.extend(YAHOO.oralb.Tools.MenuItem, YAHOO.oralb.Tools.MenuManager);
    
    YAHOO.oralb.Tools.MenuItem.prototype.init = function(){
      // create listeners for focus/blur/click/keypress and fire appropriate events
      YAHOO.util.Event.on(this.htmlElement.firstChild, YAHOO.oralb.Tools.EVENT_TYPES.clickEvent, function(){this.menuItemFocusEvent.fire(this);}, this, true);         
      //YAHOO.util.Event.on(this.htmlElement.firstChild, YAHOO.oralb.Tools.EVENT_TYPES.mouseOutEvent, function(){this.menuItemBlurEvent.fire(this);}, this, true);         
      YAHOO.util.Event.on(this.htmlElement.firstChild, YAHOO.oralb.Tools.EVENT_TYPES.focusEvent, function(){this.menuItemFocusEvent.fire(this);}, this, true);         
      YAHOO.util.Event.on(this.htmlElement.firstChild, YAHOO.oralb.Tools.EVENT_TYPES.blurEvent, function(){this.menuItemBlurEvent.fire(this);}, this, true); 
      YAHOO.util.Event.on(this.htmlElement, YAHOO.oralb.Tools.EVENT_TYPES.clickEvent, function(){this.menuItemClickEvent.fire(this);}, this, true);  
      YAHOO.util.Event.on(this.htmlElement, YAHOO.oralb.Tools.EVENT_TYPES.keyPressEvent, function(){this.menuItemKeyPressEvent.fire(this);}, this, true);     
    };
    
    YAHOO.oralb.Tools.MenuItem.prototype.setActive = function(val){
      this.active = val;
    }
   
    var createHtmlElement = function(oCfg){
      var cfg = oCfg || {}, element;
      
      if(!cfg.id)
        throw("NullArgumentException in createDiv"); // create a global Exception class
      
      var element = document.createElement("li");
      var link = document.createElement("A");

      if(cfg.url!=null)
        link.setAttribute("href",cfg.url);
      else
        link.setAttribute("href","javascript:void(0);");
        
      if(cfg.tabindex)
        link.setAttribute("tabindex",cfg.tabindex);
      link.setAttribute("target","_self");
      link.setAttribute("id",cfg.id+"_link");
      link.appendChild(document.createTextNode(cfg.title));
      element.appendChild(link);
      element.className = cfg.cssClass;      
      element.setAttribute("id",cfg.id);  
      return element;
    };
  
    var createDiv = function(oCfg){
      var cfg = oCfg || {};
      
      if(!cfg.id)
        throw("NullArgumentException in createDiv"); // create a global Exception class
        
      var newDiv = document.createElement("div");
      if(cfg.cssClass) 
        newDiv.className = cfg.cssClass;
      if(cfg.innerHtml)
        newDiv.innerHTML = cfg.innerHtml;
        
      newDiv.setAttribute("id",cfg.id);
      return newDiv;
    };
})();



(function () { // self invoking function  
  var onMenuItemFocusEventHandler = function(type, args, me){
    var context = args[0];
    var thisMenuContainerId = context._id[0];
    var element = YAHOO.util.Dom.get(context.domId);
    
    if(!YAHOO.util.Dom.hasClass(element, "menuItemActive")){
      
      // blur siblings
      var siblingMenuItems = context.getMenuItems(context._id[0], context.parentMenuId);

      if(siblingMenuItems!=null){
        for(var item in siblingMenuItems){

          YAHOO.util.Dom.setStyle(YAHOO.util.Dom.get(siblingMenuItems[item].domId), "background", "Transparent");
          
          if(YAHOO.util.Dom.hasClass(YAHOO.util.Dom.get(siblingMenuItems[item].domId), "menuItemActive"))
            YAHOO.util.Dom.removeClass(YAHOO.util.Dom.get(siblingMenuItems[item].domId), "menuItemActive");
        }
      }

      // highlight
      YAHOO.util.Dom.setStyle(element, "background", "#2679B3");
      YAHOO.util.Dom.addClass(element, "menuItemActive");
      context.clearChildMenuContainers(thisMenuContainerId);
      context.showMenuFromParent(context._id, context.parentMenuId);
    }
  }
  
  var showChildrenMenus = function(type, args, me){
    // check all menuItems to see if any are active; if true call to show that menu
    var menuItems = me.getMenuItems(args[0].menuKey, args[0].menuId);

    if(menuItems!=null){
      for(var item in menuItems){          
        if(YAHOO.util.Dom.hasClass(YAHOO.util.Dom.get(menuItems[item].domId), "menuItemActive")){
          me.showMenuFromParent(menuItems[item]._id, menuItems[item].parentMenuId);
        }
      }
    }
  }
 
  var onMenuItemBlurEventHandler = function(type, args, me){
    var context = args[0];
  }

  // event handler triggered by mouse click; set cookie for users selection.
  var onMenuItemClickEventHandler = function(type, args, me){
    var context = args[0];
	//if url is not null, and mode = consumer, then set cookie
    if(context.url!=null && context.mode == CCONSUMER) 
      createCookie(context.url); 
  }
 
  // event handler triggered by key press; set cookie for users selection.
  var onMenuItemKeyPressEventHandler = function(type, args, me){
    var context = args[0];
    // TODO: add arrow keys support and fix tabing in IE
    // check for tab or tab and shift key and focus dom element next in array of tabable items, and call mouse over event
  }


  var tabindexCount = 0; //global index to increment the li elements tab index
  
  function init(){
    var menuManager = new YAHOO.oralb.Tools.MenuManager("international");
    menuManager.layout = YAHOO.oralb.Tools.MENU_LAYOUT._HORIZONTAL;
    menuManager.addMenuContainer("site", null, {title: "Select the Site You Wish to View", cssClass: "MenuContainer", headerCssClass: "MenuContainer_hd", bodyCssClass: "MenuContainer_bd"});
    menuManager.addMenuContainer("region", "site", {title: "Select Your Region", cssClass: "MenuContainer", headerCssClass: "MenuContainer_hd", bodyCssClass: "MenuContainer_bd"});
    menuManager.addMenuContainer("country", "region", {title: "Select Your Country",cssClass: "MenuContainer", headerCssClass: "MenuContainer_hd", bodyCssClass: "MenuContainer_bd"});
    menuManager.addMenuContainer("language", "country", {title: "Select Your Language", cssClass: "MenuContainer", headerCssClass: "MenuContainer_hd", bodyCssClass: "MenuContainer_bd"});
    
    menuManager.menuItemFocusEvent.subscribe(onMenuItemFocusEventHandler);
    menuManager.menuItemBlurEvent.subscribe(onMenuItemBlurEventHandler);
    menuManager.menuItemClickEvent.subscribe(onMenuItemClickEventHandler);
    menuManager.menuItemKeyPressEvent.subscribe(onMenuItemKeyPressEventHandler);
    
    menuManager.showMenuComplete.subscribe(showChildrenMenus, menuManager);
    
    var containers = new Array();
    containers[0] = menuManager.getMenuContainer("site");
    containers[1] = menuManager.getMenuContainer("region");
    containers[2] = menuManager.getMenuContainer("country");
    containers[3] = menuManager.getMenuContainer("language");

    var siteMenu = menuManager.getMenuContainer("site").addMenu(null);
    siteMenu.addMenuItem({url:null, title:"Oral-B Consumer", active:false, cssClass:"menuItem", tabindex: ++tabindexCount}); 
    createMenu(containers, 0);
    siteMenu.addMenuItem({url:null, title:"Oral-B Professional", active:false, cssClass:"menuItem", tabindex: ++tabindexCount});
    createMenu(containers, 1);   
    menuManager.showMenuFromId("site", 0);
  }
  
  function createMenu(containers, currentSiteMenuItemId){
    var str = "";
    var arrRegions = currentSiteMenuItemId==0 ? internationalDataSet.oralbConsumer.continents : internationalDataSet.oralbProfessional.continents;
	var regionMenu = containers[1].addMenu(["site",currentSiteMenuItemId, 0]);   
    //alert(currentSiteMenuItemId)
    // loop through each region
    for(var region in arrRegions){
	
      // loop through each country
      var currentRegionMenuItemId = regionMenu.addMenuItem({url:null, title:arrRegions[region].title, active:false, cssClass:"menuItem", tabindex: ++tabindexCount});
      var arrCountries = arrRegions[region].country;
      var countryMenu = containers[2].addMenu(["region",currentRegionMenuItemId, regionMenu.getId()]);
      for(var country in arrCountries){       
        currentCountryMenuItemId = countryMenu.addMenuItem({url:null, title:arrCountries[country].title, active:false, cssClass:"menuItem", tabindex: ++tabindexCount});
       
        // loop through each language
        var arrCultures = arrCountries[country].culture;
        var menuItems = new Array();
        for(var culture in arrCultures){
          menuItems.push({mode:currentSiteMenuItemId, url:arrCultures[culture].uri, title:arrCultures[culture].title, active:false, cssClass:"menuItem", tabindex: ++tabindexCount});
        }
        containers[3].addMenu(["country",currentCountryMenuItemId, countryMenu.getId()], menuItems);
      }
    }
  }
  
  function createCookie(value) {
    var date = new Date();
    date.setTime(date.getTime()+(90*24*60*60*1000));
    var expires = "; expires="+date.toGMTString();
    document.cookie = "country="+value+expires+"; path=/";
  }
  
  function readCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    var cookieValue = null;
    for(var i=0;i < ca.length;i++) {
      var c = ca[i];
      while (c.charAt(0)==' ') c = c.substring(1,c.length);
      if (c.indexOf(nameEQ) == 0) cookieValue = c.substring(nameEQ.length,c.length);
    }
    return cookieValue;
  }
  
  var cookie = readCookie('country');

  if(cookie && (location.hash != "#intl"))
    location.replace(cookie);
  else
    YAHOO.util.Event.addListener(window, 'load', init);  
})();