Cubetree = {
  public_util: {},
  public_widgets: {},
  public_app: {}
};

(function(){

var ANIM = YAHOO.util.Anim,
    BUTTON = YAHOO.widget.Button,
	  DOM = YAHOO.util.Dom,
	  EVENT = YAHOO.util.Event,
	  LANG = YAHOO.lang,
	  LOG = YAHOO.log,
	  PANEL = YAHOO.widget.Panel;
	  
	  /**
     * The public util module provides helper methods for common Cubetree public DOM functions.
     * @module cubetree.public_util
     *
     */
    Cubetree.public_util = {

    	/**
       * Clear the form element using the passed string ID
       * @method clearFormElement
       * @param el {string} Accepts a string to use as an ID.
       */
    	clearFormElement: function(el){
    	    DOM.get(el).value = "";
    	},

    	/**
       * Clear the form element using the passed string ID
       * @method clearFormText
       * @param el {string} Accepts a string to use as an ID
       * @param instructionTxt {string} tells the user what to do
       * @param setNormal {boolean} sets the form element color to black and style to normal
       */
    	clearFormText: function(el,instructionTxt,setNormal){
    	    var theField = DOM.get(el),
    	        _setNormal = (setNormal)? true : false;
    	        
    	    if (theField.value === instructionTxt){
    	      this.clearFormElement(el);
    	    }

    	    if (_setNormal){
            DOM.setStyle(el,"color","#000");
            DOM.setStyle(el,"fontStyle","normal");
    	    }
    	},
    	
    	/**
       * Open a popup window or return false if popup blocked
       * @method openWindow
       * @param sUrl {string} the url for the window (can be set to false or null if you wish to interact with the win through JS).
       * @param sName {string} name for the new window (defaults to "_blank").
       * @param oProperties {object} window properties default to any window.open JS function passed as a name: "value".
       */
    	openWindow: function(sUrl,sName,oProperties){

    	    var url = (sUrl) ? sUrl : '',
              name = (sName) ? sName : "_blank",
              // Default is opening a window the same dimensions as the current window.
              specs = "width=" + DOM.getClientWidth() + ",height=" + DOM.getClientHeight() + ",toolbar=1,location=1,status=1,menubar=1,resizable=1,scrollbars=1";

    	    if (LANG.isObject(oProperties)){
            var propertyString = "";

            for (o in oProperties){
                propertyString += o + "=" + oProperties[o] + ",";
            }

            specs = propertyString.substring(0,(propertyString.length - 1)); // Cut off the last ","
    	    }

    	    var theWindow = window.open(url,name,specs);

    	    return (theWindow)? theWindow : false; // return the window object or false if popup blocked
    	},
    	
    	/**
       * Allows you to set form text in a field
       * @method setFormText
       * @param el {string} Accepts a string to use as an ID
       * @param txt {string} text you want to populate the field
       * @param txtColor {string/boolean} change the color of the text in the field or leave current field color
       * @param fontStyle {string/boolean} set a font style for the text or leave the current style
       * @param overrideText {boolean} sets the form element text to the value of the text
       */
    	setFormText: function(el,txt,txtColor,fontStyle,overrideText){
    	    var theField = DOM.get(el),
    	        _fontStyle = (fontStyle)? fontStyle : false,
    	        _overrideCurrentTxt = (overrideText)? true : false,
    	        _txtColor = (txtColor)? txtColor : false;
    	        
	        if (_txtColor && LANG.trim(theField.value) === '' || _overrideCurrentTxt){
            DOM.setStyle(el,"color",_txtColor);
    	    }

    	    if (_fontStyle && LANG.trim(theField.value) === ''  || _overrideCurrentTxt){
            DOM.setStyle(el,"fontStyle",_fontStyle);
    	    }
          
          if (LANG.trim(theField.value) === '' || _overrideCurrentTxt){
            theField.value = txt;
          }

    	}
    };// End YAHOO.cubetree.public_util  
	  
	  
  /**
   * The widgets module provides helper methods for common public Cubetree reusable functions.
   * @module cubetree.public_widgets
   *
   */
  Cubetree.public_widgets = {
    
    /**
     * YAHOO.cubetree.widgets.alertDisplay returns a skinned YUI panel with which to display alert messages 
     * @method alertDisplay
     * @param msg the alert message/HTML passed into the function to be displayed in the panel
     * @param _alertPanel {object} YUI panel object
     * @param _footerContent {string} footer content to be passed into the panel footer
     * @param _render {boolean} set to false until the panel is rendered
     * @return changeMsg
     * @return hide
     * @return panel
     * @return show
     */
    alertDisplay: (function(){

    	var _alertPanel = new PANEL("alertDisplayPanel", {
    		width: "336px", 
    		fixedcenter: true, 
    		constraintoviewport: true, 
    		underlay:"none", 
    		close: false, 
    		visible: false, 
    		modal: true,
    		zIndex: 400} ),
    		_render = false;

      /**
    	 * Build the contents of the error message panel
    	 * @private
    	 * @param oMsg {object} the header and body error messages passed into the function to be displayed in the panel
    	 *        oMsg.container = the container element to append this panel to, default is document.body if not specified
    	 *        oMsg.header = header content        
    	 *        oMsg.body = body content
    	 *        oMsg.footer = footer content
    	 */
    	var _buildPanel = function(oMsg) {
    		oMsg.header = "<h3>" + oMsg.header + "</h3>" || "&nbsp;";
    		oMsg.body = oMsg.body || "&nbsp;";
    		oMsg.footer = oMsg.footer || "&nbsp;";
        oMsg.container = (oMsg.container) ? oMsg.container : document.body; 
			  oMsg.modal = (oMsg.modal) ? oMsg.modal : true; 

    		_alertPanel.setHeader(oMsg.header);
    		_alertPanel.setBody(oMsg.body);
    		_alertPanel.setFooter(oMsg.footer);
			  _alertPanel.cfg.setProperty("modal", oMsg.modal );
    		_alertPanel.render(oMsg.container);
    		_render = true;
    	};

    	return {
    		changeMsg: function(oMsg){
    			this.show(oMsg);	
    		},
    		hide: function(){
    			_alertPanel.hide();
    		},
    		panel: function(){
    			return _alertPanel;
    		},
    		show: function(oMsg){
    			if(!_render){
    				_buildPanel(oMsg);
    				_alertPanel.show();
    			}
    			else{
    			    if (oMsg.header){ _alertPanel.setHeader('<h3>' + oMsg.header + '</h3>'); }
    				_alertPanel.setBody(oMsg.body);
    				if (oMsg.footer){ _alertPanel.setFooter(oMsg.footer); }
    				_alertPanel.show();
    			}
    		}
    	}; // End return

    })(),
    
    /**
     * Manage instructional text within a form field
     * @method manageFormFieldHelper
     * @param el {string} Accepts a string to use as an ID for the form elem
     * @param instructionTxt {string} tells the user what to do
     * @param txtColor {string} identify a text color for the field, otherwise default to grey
     * @param cssClass {string} optional CSS class for fake pwd field
     * @param focusField {boolean} true if you want the field selected (will not work on password). WILL NOT WORK IE7 OR BELOW.
     */
    manageFormFieldHelper: function(el,instructionTxt,txtColor,cssClass,focusField){
      
      var _cssClass = cssClass || false,
          _fakePwdFieldID = false,
          _fieldElem = DOM.get(el),
          _focusField = focusField || false,
          _helpTxtColor = (txtColor)? txtColor : "#afafaf",
          _ieVersion = YAHOO.env.ua.ie,
          _isPasswordField = false,
          _passwordFieldParent = false;

      /**
       * Create a fake password field to display help text
       * @method _createFakePasswordField
       * @private
       */
      function _createFakePasswordField(){
        _passwordFieldParent = DOM.getAncestorBy(DOM.get(el));
        _fakePwdFieldID = DOM.generateId() + "_password_placeholder";
        
        var fakePwdField = document.createElement("input");
            fakePwdField.type = 'text';    
            fakePwdField.id = _fakePwdFieldID;
            fakePwdField.name = _fakePwdFieldID;
            fakePwdField.value = instructionTxt;
            fakePwdField.tabIndex = _fieldElem.tabIndex;
            if (_cssClass){
              DOM.addClass(fakePwdField,_cssClass);
            }
            
        _passwordFieldParent.appendChild(fakePwdField);
        LOG("password field appended");
        
        EVENT.addListener(_fakePwdFieldID,"focus",function(){
          DOM.setStyle(_fakePwdFieldID,'display','none');
          DOM.setStyle(el,'display','inline');
          _fieldElem.focus();
          LOG("fake password field focus fired");
        });
            
        DOM.setStyle(el,'display','none');
      } 
      
      /**
       * Manage the field blur state
       * Re set the background color to active and populate the field if empty
       * @method _doFieldBlur
       * @private
       */
      function _doFieldBlur(e){
        if (_isPasswordField && (LANG.trim(_fieldElem.value) === '' || (LANG.trim(_fieldElem.value) !== '' && LANG.trim(_fieldElem.value) === instructionTxt))){
          DOM.setStyle(el,'display','none');
          DOM.setStyle(_fakePwdFieldID,'display','inline');
        } else {
          Cubetree.public_util.setFormText(el,instructionTxt,_helpTxtColor);
        }
        DOM.setStyle(el,'background','#fff');
        
        // Remove keydown events for the focusField if set
        if (EVENT.getListeners(el,"keyup")){
          EVENT.removeListener(el, "keyup");
          EVENT.addListener(el,"focus", _doFieldFocus);
        }
        LOG('_doFieldBlur fired');
      }
      
      /**
       * Manage the field focus state
       * Set the background color to active and clear the field if the instuction text is present
       * @method _doFieldFocus
       * @private
       */
      function _doFieldFocus(e){
        DOM.setStyle(el,'background','#fffddd');
        Cubetree.public_util.clearFormText(el,instructionTxt,true);
        LOG('_doFieldFocus fired');
      }
      
      /**
       * Set the initial state for the form field. 
       * Check to see if the field is populated, or is a password field.
       * @method _setFieldState
       * @private
       */
      function _setFieldState(){
        if (LANG.trim(_fieldElem.value) === '' || (LANG.trim(_fieldElem.value) !== '' && LANG.trim(_fieldElem.value) === instructionTxt)){
          
          var _fieldToStyle = el;
          
          if (_fieldElem.getAttribute('type') === 'password'){
            _isPasswordField = true;
            _createFakePasswordField();
            _fieldToStyle = _fakePwdFieldID;
          }
          
          DOM.setStyle(_fieldToStyle,'color',_helpTxtColor); 
          if (!_isPasswordField){
            if ((_ieVersion > 6 || _ieVersion === 0) && _focusField){
              listeners = EVENT.getListeners(el);
              EVENT.removeListener(el,"focus");
  
             _fieldElem.value = instructionTxt;
             _fieldElem.select();
             _fieldElem.focus();
             DOM.setStyle(el,'background','#fffddd');
             LOG("focusField selected");
             
             EVENT.addListener(el, "keyup", function(ev){
               if (this.value != instructionTxt){
                  DOM.setStyle(el,"color","#000");
                  DOM.setStyle(el,"fontStyle","normal");
                  this.focus();
                }
               LOG("keyup listener fired.");
             });
             
            } else {
             _fieldElem.value = instructionTxt;  
            }
          }
        }
      }
      
      EVENT.onDOMReady(function(){
        // Set timeout for browser field populate on DOM load. This avoids conflict with autocomplete.
        setTimeout(function(){
          _setFieldState();
        }, 100);
      });
      
      EVENT.addListener(el,"focus",_doFieldFocus);
      EVENT.addListener(el,"click",_doFieldFocus); //need this too because user could click on a field that already has focus
      
      EVENT.addListener(el,"blur",_doFieldBlur);
      
    },
    
    /**
     * If the notice message is in the DOM, use the YUI animation to scroll it closed 
     * @method NoticeScrollUp
     * @param sContainer {string} The notice container you want to disappear.
     * @param sDelay {integer} number of miliseconds for the setTimeout.
     */
    noticeScrollUp: function(sContainer,sDelay){
      if(DOM.inDocument(sContainer)){
        var timer = setTimeout(function(){
          var fadeOut = new ANIM(sContainer,{opacity: {to: 0}});
              fadeOut.duration = 0.5;
          var rollUp = new ANIM(sContainer,{height: {to: 0}});
              rollUp.duration = 0.5;
          fadeOut.onComplete.subscribe(function(){
            if(YAHOO.env.ua.ie === 6){
              YAHOO.cubetree.util.removeDOMNode(sContainer);
            } else { 
              rollUp.onComplete.subscribe(function(){
                YAHOO.cubetree.util.removeDOMNode(sContainer);
              });
              rollUp.animate();
            }
          });
          fadeOut.animate();
        },sDelay);
      }
    },
    
    /**
     * Check through the DOM and replace all of the submit buttons with styled YUI buttons.
     * @method styleButtons
     * @param _buttons {array} the buttons on the page that will be replaced by the button widget.
     * @param _styledButtons {array} collection of YUI button objects.
     */	
  	styleButtons: function(){
      var _buttons = DOM.getElementsBy(_testInput,"input"),
          _styledButtons = [];

      var tabindex;
      for (i=0;i<_buttons.length;i++){

        var btn_class;
        if (DOM.hasClass(_buttons[i],"form-main")){
          btn_class = "form-main";
        }
        else if (DOM.hasClass(_buttons[i],"form-disabled")){
          btn_class = "form-disabled";
        } else if (DOM.hasClass(_buttons[i],"form-alt")){
          btn_class = "form-alt";
        } else if (DOM.hasClass(_buttons[i],"form-post")){
          btn_class = "form-post";
        } else {
          btn_class = "form-secondary";
        }

        //check against undefined just in case some weird browsers don't support tabIndex property
        //tabIndex of 0 is same as not specifying a tabindex in html; it's also the default value returned by tabIndex property
        tabindex = (typeof _buttons[i].tabIndex === 'undefined') ? 0 : _buttons[i].tabIndex;

        _styledButtons[i] = new BUTTON(_buttons[i], {tabindex:tabindex});
        _styledButtons[i].addStateCSSClasses(btn_class);
      }

      /**
       * Test to make sure input type is submit. Return true if it is.
       * @private
       * @method _testInput
       */
      function _testInput(e){
        if (e.type === "submit" || e.type === "reset"){ 
          return true;
        } else {
          return false;
        }
      } 
  	} // end styleButtons
  }; // End YAHOO.cubetree.public_widgets


  EVENT.onContentReady("bd", function(){
    Cubetree.public_widgets.styleButtons();
  });
  EVENT.onDOMReady(function(){
    Cubetree.public_widgets.noticeScrollUp("noticeMessage",5000);
  });

})();
