//<%--
//********************************************************************
//*-------------------------------------------------------------------
//* Licensed Materials - Property of IBM
//*
//* WebSphere Commerce
//*
//* (c) Copyright IBM Corp.  2007
//* All Rights Reserved
//*
//* US Government Users Restricted Rights - Use, duplication or
//* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
//*
//*-------------------------------------------------------------------
//*
//--%>

  dojo.registerModulePath("wc", "wc");
  
  dojo.require("dojo.io.*");
  
  //product quick view with tooltip widget
  dojo.require("wc.widget.ProductQuickView");
  dojo.require("wc.widget.BaseContent");
  dojo.require("wc.widget.ToolTipContent");

  //category menu support
  dojo.require("dojo.widget.Button");
  dojo.require("dojo.widget.Menu2");
    
  //reload widgets when parts of the page has been re-loaded from server
  dojo.require("dojo.xml.Parse");
  
  //publish and subscribe event support
  dojo.require("dojo.event.*");
  
  dojo.require("wc.widget.ScrollablePane");
  dojo.require("dojo.animation.*");
  dojo.require("dojo.lfx.*");
  dojo.require("dojo.string.extras");
  dojo.require("dojo.collections.ArrayList");

  dojo.require("dojo.widget.TabContainer");
  dojo.require("dojo.widget.ContentPane");
  dojo.require("dojo.widget.Button");
  dojo.require("dojo.widget.Tree");
  dojo.require("dojo.widget.TreeSelector");

  dojo.require("dojo.undo.browser");

  dojo.require("wc.widget.RefreshArea");
  dojo.require("wc.render.RefreshController");
  dojo.require("wc.render.Context");
  dojo.require("dojo.widget.Tooltip");
  
Common={
  //All the global variables declarations will be here
  errorMessages: {},
  
  //summary: This is a collection of commonly used functions
  containsDoubleByte:function(target) {
    // summary:Checks whether a string contains a double byte character
    // target = the string to be checked
    //
    // Return true if target contains a double byte char; false otherwise
     var str = new String(target);
     var oneByteMax = 0x007F;

     for (var i=0; i < str.length; i++){
      chr = str.charCodeAt(i);
      if (chr > oneByteMax) {return true;}
     }
     return false;
  },
  
  
  isValidEmail:function(strEmail){
    //summary: A simple function to validate an email address
    // It does not allow double byte characters
    // strEmail = the email address string to be validated
    //
    // Return true if the email address is valid; false otherwise
    if (containsDoubleByte(strEmail)){
      return false;
    }
    
    if(strEmail.length == 0) {
      return true;
    } else if (strEmail.length < 5) {
         return false;
      }else{
        if (strEmail.indexOf(" ") > 0){
              return false;
          }else{
            if (strEmail.indexOf("@") < 1) {
                  return false;
              }else{
                if (strEmail.lastIndexOf(".") < (strEmail.indexOf("@") + 2)){
                      return false;
                  }else{
                      if (strEmail.lastIndexOf(".") >= strEmail.length-2){
                        return false;
                      }
                  }
              }
          }
      }
      return true;
  },
  
  getCurrentYear: function(){
    //summary: returns the current year. 
    return new Date().getFullYear();
  }, 
  
  getCurrentMonth: function(){
    //summary: returns the current month. January is 1, and Decement is 12. 
    return new Date().getMonth()+1; 
  }, 
  
  getCurrentDay: function(){
    //summary: returns the current day of the current month, starting from 1. 
    return new Date().getDate();
  }, 
  
  getRenderContextProperty : function(/*wc.render.Context*/context, /*String*/propertyName){
    //summary: retrieves the value of the property from a render context
    //description: This function retrieves the value of the property whose name is propertName
    //  from the given context. 
    //returns: null if the context is null. undefined if the property is not found. 
    //  otherwise, the value of the property int he given context. 
    dojo.debug("enter getRenderContextProperty with propertyName = "+propertyName);
    if(context == null){
      dojo.debug("context is null. Return null...");
      return null;
    }
    
    var result = context.properties[propertyName]
    dojo.debug("the found property value is: "+result);
    
    return result;  
  }, 
  
  loadAddressContentFromURL: function(/*String*/contentURL, /*String*/areaID, /*String*/method, /*Object?*/params){
    //summary: loads the response from invoking a given URL to the area that has the given ID. 
    //description: This function invokes the given contentURL, and then updates the area whose ID is 
    //  the given areaID with the response content. 
    //contentURL: the URL used to get new content
    //areaID: the ID of the area that will be updated. The area can be anything that supports
    //  innerHTML, such as table, and div. 
    //method: The HTTP method used for invoking the given URL. The default is GET.
    //params: Optional parameters used when invoking URL
    var contentArea = document.getElementById(areaID);
    if(!contentArea){
      return; 
    }
    
    dojo.io.bind({
      url: contentURL,
      method: method?method:'GET',
      load: function(type, data, evt){
        contentArea.innerHTML = data;
        cursor_clear(); 
      },
      mimetype: "text/html", 
      params: params
    });
    cursor_wait();
  }, 
  
  loadAddressContentFromForm: function(form, areaID, params){
    //summary: loads the response from submitting a given form to the area that has the given ID. 
    //description: This function submits a given form, and then updates the area whose ID is 
    //  the given areaID with the response content. 
    //form: the form that is to be submitted
    //areaID: the ID of the area that will be updated. The area can be anything that supports
    //  innerHTML, such as table, and div. 
    var contentArea = document.getElementById(areaID);
    if(!contentArea){
      return; 
    }
    
    dojo.io.bind({
      formNode: form, 
      load: function(type, data, evt){
        contentArea.innerHTML = data;
        cursor_clear(); 
      },
      mimetype: "text/html", 
      params: params
    });
    cursor_wait();
  }, 
  
  
  getErrorFields: function(serviceResponse){
    if(!serviceResponse){
      return [];  
    }
    
    var result = serviceResponse.errorMessageParam;
    if(dojo.lang.isArrayLike(result)){
      return result;  
    }else{
      return [result];  
    }
  }, 
  
  reportServiceError: function(/*String*/formName, /*JSONObject*/serviceResponse){
    dojo.require("dojo.html.*");
    dojo.lang.forEach(Common.getErrorFields(serviceResponse), function(field){
      var input = document.forms[formName].elements[field];
      input.style.border="thick double red ";
      input.focus();
      input.value="Please enter this field";
    }); 
  },  
  
  setErrorMessage:function(key, msg) {
  ///////////////////////////////////////////////////////////////////
  // summary: This function is used to initialize the error messages object 
  //  with all the required error messages.
  // Description: Setup a JS object with any key/value.
  // key: The key used to access this error message.
  // msg: The error message in the correct language.
  //////////////////////////////////////////////////////////////////
    this.errorMessages[key] = msg;
  },
  
  formErrorHandle:function(serviceResponse,formName,parentDivName){
      
  ///////////////////////////////////////////////////////////////////
  // summary: This function will show the an error message tooltip
  //    around the input field with the problem.
  // Description: The function assumes the "serviceResponse" is the
  //    JSON object from a WebSphere Commerce exception. The error 
  //    field is in the serviceResponse.errorMessageParam and the
  //    error message is in the serviceResponse.errorMessage.
  // serviceResponse: The JSON object with the error data.
  // formName: The name of the form where the error field is.
  // parentDivName: The name of the division area that contains the
  //    form with the error field.
  //////////////////////////////////////////////////////////////////  
   this.formErrorHandleClient(serviceResponse.errorMessageParam, serviceResponse.errorMessage, formName, parentDivName);

  },

  formErrorHandleClient:function(errorInputField,errorMessage,formName,parentDivName){
      

  ///////////////////////////////////////////////////////////////////
  // summary: This function will show the an error message tooltip
  //    around the input field with the problem.
  // Description: The function takes the error field name and the 
  //    error message to display.
  // errorInputField: The name of the field with error.
  // errorMessage: The error message to display.
  // formName: The name of the form where the error field is.
  // parentDivName: The name of the division area that contains the
  //    form with the error field.
  //////////////////////////////////////////////////////////////////  
   this.hideErrorNode();  
   var form = document.forms[formName];
   var parent =document.body;
   if(form.elements[errorInputField]){
     var input = form.elements[errorInputField];
     input.focus();     
     input.onclick=(function() {Common.hideErrorNode();});
     dojo.event.connect(this.inputNode, "onchange", Common, "hideErrorNode");
     //input.onchange=(function() {Common.hideErrorNode();});
     var x = dojo.html.getAbsoluteX(input, true)+ input.offsetWidth;
     var y = dojo.html.getAbsoluteY(input, true);
     this.setErrorMsg(parent,errorMessage,x,y);
   }else{
     Common.hideErrorNode();
     alert(errorMessage);
   }
  },

  setErrorMsg:function(parentNode,content,x,y){
    

  ///////////////////////////////////////////////////////////////////
  // summary: This function will set the Error Message and position for the "errorNode".
  // Description: This function will takes "parentNode" , "content" and positions x,y  
  // as input arguments, and set those to "errorNode" 
  // if "errorNode" is not created,then it will call "createErrorNode" 
  // method first before setting message and position.
  //////////////////////////////////////////////////////////////////  

   if(document.getElementById('bubble')) var errorNode = document.getElementById('bubble');
   else var errorNode = this.createErrorNode(parentNode);
   
   var msg=document.getElementById('bubble_content');
   //msg.innerHTML = content.replace(/</g,'').replace(/>/g,'');
   msg.innerHTML = content;
   errorNode.style.left = x +"px";
   errorNode.style.top = y + "px"; 
  },
   
  createErrorNode:function(parentNode) {     
  ///////////////////////////////////////////////////////////////////
  // summary: This function will create new "errorNode".
  // Description: This function will take "parentNode" as input arguments,  
  // it will create new "errorNode" and appends that to "parentNode", then
  // it will return that "errorNode".
  //////////////////////////////////////////////////////////////////  
   
   var errorNode = document.createElement("div");
   errorNode.id="bubble";
   var leftEnd = errorNode.appendChild(document.createElement("div"));
   leftEnd.className="lefttail";
   var content = errorNode.appendChild(document.createElement("div"));
   content.className="bubble_content";
   content.id="bubble_content";
   var rightEnd = errorNode.appendChild(document.createElement("div"));
   rightEnd.className="rightend";

   errorNode = parentNode.appendChild(errorNode);
   return errorNode;
  },
  hideErrorNode:function(){
  ///////////////////////////////////////////////////////////////////
  // summary: This function will remove the "errorNode".
  // Description: This function will remove the "errorNode" if its there,  
  //////////////////////////////////////////////////////////////////  
  if(document.getElementById('bubble'))
    dojo.dom.removeNode(document.getElementById('bubble'));
  },  
   
  containsDoubleByte:function (target) {
      
  // Summary:Checks whether a string contains a double byte character.
  // Description:Checks whether a string contains a double byte character.
  // target: String
  //     the string to be checked
  //
  // Return true if target contains a double byte char; false otherwise
  
        var str = new String(target);
        var oneByteMax = 0x007F;

        for (var i=0; i < str.length; i++){
            chr = str.charCodeAt(i);
            if (chr > oneByteMax) {
              return true;
            }
        }
        return false;
  },
 
  isValidEmail:function(strEmail){
  
  // Summary: A simple function to validate an email address
  // Description: This function validate email address. It does not allow double byte characters
  //    Return true if the email address is valid; false otherwise
  // strEmail: String
  //           the email address string to be validated

  
  
  // check if email contains dbcs chars
    if (this.containsDoubleByte(strEmail)){
      return false;
    }
  
    if(strEmail.length == 0) {
      return true;
    } else if (strEmail.length < 5) {
               return false;
          }else{
              if (strEmail.indexOf(" ") > 0){
                          return false;
                  }else{
                      if (strEmail.indexOf("@") < 1) {
                                return false;
                        }else{
                              if (strEmail.lastIndexOf(".") < (strEmail.indexOf("@") + 2)){
                                        return false;
                                  }else{
                                          if (strEmail.lastIndexOf(".") >= strEmail.length-2){
                                            return false;
                                          }
                                  }
                          }
                  }
          }
          return true;
  },

  isValidUTF8length: function(UTF16String, maxlength) {
  //////////////////////////////////////////////////////////
  // summary: This function will check if the number of bytes of the string
  // is within the maxlength specified.
  // Description: Check if the number of bytes is within the maxlength specified.
  //
  // UTF16String: the UTF-16 string
  // maxlength: the maximum number of bytes allowed in your input field
  //
  // Return false is this input string is larger then arg2
  // Otherwise return true...
  //////////////////////////////////////////////////////////
      if (this.utf8StringByteLength(UTF16String) > maxlength) return false;
      else return true;
  },
  
  utf8StringByteLength: function(UTF16String) {
  //////////////////////////////////////////////////////////
  // summary: This function will count the number of bytes
  // represented in a UTF-8 string
  // Description: Check if the number of bytes is within the maxlength specified.
  //
  // UTF16String: the UTF-16 string you want a byte count of...
  // Return the integer number of bytes represented in a UTF-8 string
  //////////////////////////////////////////////////////////
    if (UTF16String === null) return 0;
    var str = String(UTF16String);
    var oneByteMax = 0x007F;
    var twoByteMax = 0x07FF;
    var byteSize = str.length;
  
    for (i = 0; i < str.length; i++) {
      chr = str.charCodeAt(i);
      if (chr > oneByteMax) byteSize = byteSize + 1;
      if (chr > twoByteMax) byteSize = byteSize + 1;
    }  
    return byteSize;
  },
  IsNumeric : function (text,allowDot)
  {
    // summary: this function will check whether a entered text is a numaric or not.
    // description: this function will take the 'text' and allowDot as input characters 
    // and will check whether the text is numaric or not  
    // allowDot : is a boliyan wich specifies whether to consider the '.' or not.
     if(allowDot) var ValidChars = "0123456789.";
     else var ValidChars = "0123456789";
    
     var IsNumber=true;
     var Char;

   
     for (i = 0; i < text.length && IsNumber == true; i++) 
      { 
      Char = text.charAt(i); 
      if (ValidChars.indexOf(Char) == -1) 
       {
       IsNumber = false;
       }
      }
     return IsNumber;
     
  },
  
   goBack:function(){
  
  // summary: this function belong to HistoryTracking for receiving Back notifications
  // description: this function belong to HistoryTracking for receiving Back notifications  
  
    document.getElementById(this.elementId).innerHTML = this.content;
    
        },
        
        goForward:function(){
       
  // summary: this function belong to HistoryTracking for receiving forward notifications
  // description:this function belong to HistoryTracking for receiving forward notifications  
  
          document.getElementById(this.elementId).innerHTML = this.content;
          
        },
  
  popup: function(url, windowWidth, windowHeight, windowName) {
    var width  = windowWidth || 300;
    var height = windowHeight || 200;
    var left   = (screen.width  - width)/2;
    var top    = (screen.height - height)/2;
    var params = 'width='+width+', height='+height;
    params += ', top='+top+', left='+left;
    params += ', directories=no';
    params += ', location=yes';
    params += ', menubar=no';
    params += ', resizable=yes';
    params += ', scrollbars=yes';
    params += ', status=yes';
    params += ', toolbar=no';
    newwin=window.open(url, windowName, params);
    if (window.focus) {newwin.focus()}
    return false;
  },
          
  
  HistoryTracker:function(content, elementId, changeUrl){
  
  // summary: History state object for history tracking
  // description:History state object for history tracking
  // content: String
  //    the html to be displayed
  // elementId: String
  //    the name of the DOM object
  // changeUrl: String
  //    the identifier for the current state of this page
  
    this.content = content;
    this.elementId = elementId;
    //TODO: commenting this out breaks FF 1.5. Others? Can't seem to find iframe id/name?
    this.changeUrl =  changeUrl;
    
    
  }
} 
  Common.HistoryTracker.prototype.back = Common.goBack;
  Common.HistoryTracker.prototype.forward=Common.goForward;  
  
