/***********************************************************************************************************************
| object/Address.js
***********************************************************************************************************************/
var _SBOX_VALUES_STATES           =new Array("","AL","AK","AZ","AR","CA","CO","CT","DC","DE","FL","GA","HI","ID","IL","IN","IA","KS","KY","LA","ME","MD","MA","MI","MN","MS","MO","MT","NE","NV","NH","NJ","NM","NY","NC","ND","OH","OK","OR","PA","PR","RI","SC","SD","TN","TX","UT","VT","VA","WA","WV","WI","WY","VI");
var _SBOX_LABELS_STATES           =new Array("","Alabama","Alaska","Arizona","Arkansas","California","Colorado","Connecticut","Dist. of Columbia","Delaware","Florida","Georgia","Hawaii","Idaho","Illinois","Indiana","Iowa","Kansas","Kentucky","Louisiana","Maine","Maryland","Massachusetts","Michigan","Minnesota","Mississippi","Missouri","Montana","Nebraska","Nevada","New Hampshire","New Jersey","New Mexico","New York","North Carolina","North Dakota","Ohio","Oklahoma","Oregon","Pennsylvania","Puerto Rico","Rhode Island","South Carolina","South Dakota","Tennessee","Texas","Utah","Vermont","Virginia","Washington","West Virginia","Wisconsin","Wyoming","Virginia");
var _SBOX_VALUES_PROVS            =new Array("","AB","BC","MB","NB","NL","NT","NS","NU","ON","PE","QC","SK","YT");
var _SBOX_LABELS_PROVS            =new Array("","Alberta","British Columbia","Manitoba","New Brunswick","Newfoundland","NW Territories","Nova Scotia","Nunavut","Ontario","P.E.I","Quebec","Saskatchewan","Yukon ");
var _SBOX_VALUES_COUNTRIES        =new Array();


/***********************************************************************************************************************
| CONSTRUCTOR -
\**********************************************************************************************************************/
function Address(strParentId, strAddressee, strBizName, strAddr1, strAddr2, strCity, strRegion, strPostalCode, strCountry, charAddressType, strId) {
   this.className ="Address";
   this.strParentId =strParentId;      // foreign key (eg, customer # or invoice #)
   this.strAddressee =strAddressee;
   this.strBizName =strBizName;
   this.strAddr1 =strAddr1;
   this.strAddr2 =strAddr2;
   this.strCity =strCity;
   this.strRegion =strRegion;
   this.strPostalCode =strPostalCode;
   this.strCountry =strCountry;
   charAddressType ? this.charAddressType =charAddressType : this.charAddressType ="R";
   this.strId =strId;

   for(var member in this) {
      if(!this[member]) { this[member] =""; }
   }
}






/***********************************************************************************************************************
| toString
\**********************************************************************************************************************/
Address.prototype.toString =function() {
   var strToString ="";

   strToString =this.strId +" " +this.strAddressee +" " +this.strBizName +" " +this.strAddr1 +" " +this.strAddr2 +" " +
                this.strCity +" " +this.strRegion +" " +this.PostalCode +" " +this.strCountry +" " +this.charAddressType;

   return strToString;
}





/***********************************************************************************************************************
| sanityCheck
| Performs a sequence of checks on vital data to ensure all values are legal.
| returns: either "sane" or a '|' delimited list of sanity check failures.
\**********************************************************************************************************************/
Address.prototype.sanityCheck =function() {
   var strDiagnosis ="";
   var strDiagnosisChild ="";

   this.clean();

   if(!this.strCountry) { this.strCountry =""; }

   if(!this.strAddressee && !this.strBizName) { strDiagnosis +="missing~Addressee|"; }
   if(!this.strAddr1) { strDiagnosis +="missing~Street Address|"; }
   if(this.strCountry.toLowerCase() == "usa") {
      if(!this.strRegion) { strDiagnosis +="missing~State|"; }
      if(!this.strPostalCode) { strDiagnosis +="missing~PostalCode|"; }
   }
   if(this.strCountry.toLowerCase() == "canada") {
      if(!this.strRegion) { strDiagnosis +="missing~Province|"; }
      if(!this.strPostalCode) { strDiagnosis +="missing~PostalCode|"; }
   }
   if(!this.strCountry) { strDiagnosis +="missing~Country|"; }
   if(!this.charAddressType) { strDiagnosis +="missing~Residential or Commercial?|"; }

   if(strDiagnosis == "") { strDiagnosis ="sane"; }
   else { strDiagnosis ="className~Address|id~" +this.strId +"|" +strDiagnosis; }

   return strDiagnosis;
}






/***********************************************************************************************************************
| populateSboxStates
| Populates a select box with US states.
| sbox: select box node
| selected: value selected in select box
\**********************************************************************************************************************/
Address.prototype.populateSboxStates =function(sbox, selected) {
   var i, j;
   var optVal, optLbl;
   if(sbox && sbox.options && !sbox.options[0]) {
      j =_SBOX_VALUES_STATES.length;
      for(i =0; i < j; i++) {
      opt =document.createElement("option");
      opt.value =_SBOX_VALUES_STATES[i];
      opt.text  =_SBOX_LABELS_STATES[i];

      try         { sbox.add(opt,null); }               //DOM2 (Firefox) method
      catch (e)   { sbox.add(opt,sbox.length); }        //IE-only method

      if(opt.value == selected) { opt.selected =true; }    //WARNING MUST BE AFTER SBOX.ADD OR IE WILL BARF
      }
   }
}






/***********************************************************************************************************************
| isAddressBlank
| Checks if address is blank (excluding strParentId).
| returns: true if address is blank.
\**********************************************************************************************************************/
Address.prototype.isAddressBlank =function() {
   var boolAddressBlank =true;
   var field;

   for(field in this) {
      if(field != "strParentId" && this[field] && "number|bool|string".indexOf(this[field]) > 0) {
         boolAddressBlank =false;
         break;
      }
   }

   return boolAddressBlank;
}






/***********************************************************************************************************************
| isAddressValid
| Checks if address is valid.
| returns: the string "valid", or a string giving detailing why address is invalid (reasons are '|' delimited).
\**********************************************************************************************************************/
Address.prototype.isAddressValid =function() {
   var strAddressValid ="";
   var regxZipCode =/(^\d{5}$)|(^\d{5}-\d{4}$)/;
   var regxPostalCode =/^\D{1}\d{1}\D{1}\-?\d{1}\D{1}\d{1}$/;

  var isValid = validFormat.test(postalCode);

   if(this.strAddr1 == "" && this.strAddr2 == "") { strAddressValid +="All addresses must have at least one address line.|"; }
   if(this.strCountry == "") {  strAddressValid +="All addresses must have a country.|"; }
   if(this.strCountry.toLowerCase == "usa") {
      if(this.strRegion == "") {  strAddressValid +="Addresses in the USA must have a state.|"; }
      if(this.strPostalCode == "") {  strAddressValid +="Addresses in the USA must have a postal code.|"; }
      else if(!regxZipCode.test(this.strPostalCode)) { strAddressValid +="US postal code format must be '#####' or '######-####'.|"; }
   }
   if(this.strCountry.toLowerCase == "canada") {
      if(this.strRegion == "") {  strAddressValid +="Addresses in Canada must have a province.|"; }
      if(this.strPostalCode == "") {  strAddressValid +="Addresses in Canada must have a postal code.|"; }
      else if(!regxZipCode.test(this.strPostalCode)) { strAddressValid +="Canadian postal code format must be 'A#A-#A#' or 'A#A#A#'.|"; }
   }

   if(strAddressValid == "") { strAddressValid ="valid"; }

   return strAddressValid;
}






/***********************************************************************************************************************
| isAddressInArray
| Checks if an address is duplicated within an array of addresses.
| arrAddresses: addresses to check against.
| returns: position of address in array, or -1.
\**********************************************************************************************************************/
Address.prototype.isAddressInArray =function(arrAddresses) {
   var intAddrInArray =-1;
   var i,j;

   if(objAddresses && objAddresses[0]) {
      boolAddrPresent =true;
      j =arrAddresses.length;
      for(i =0; i < j; i++) {
         if(this.checkIfDuplicate(arrAddresses[i])) {
            boolAddrInArray =i;
            break;
         }
      }
   }

   return intAddrInArray;
}






/***********************************************************************************************************************
| checkIfDuplicate
| Checks if an address is a duplicate.
| objAddress: address to check against.
| returns: true if address is a duplicate.
\**********************************************************************************************************************/
Address.prototype.checkIfDuplicate =function(objAddress) {
   var boolAddrIsDupe =true;
   var field,types;

   for(field in this) {
      types ="boolean|string|number";
      if(types.indexof(typeof this[field]) >= 0) {
         if(this[field] != objAddress[field]) { boolAddrIsDupe =false; }
      }
   }

   return boolAddrIsDupe;
}






/***********************************************************************************************************************
| getClone
| returns: a clone.
\**********************************************************************************************************************/
Address.prototype.getClone =function() {
   var undefined;
   var clone =new Address();
   var field;

   for(field in this) {
      if(typeof this[field] != "object") { clone[field] =this[field]; }
      else if(this[field] instanceof Array) { clone[field] =new Array(); }
      else { clone[field] =undefined; }
   }

   return clone;
}






/***********************************************************************************************************************
| clean
| Clean illegal characters from data members.
| return: boolean: successful?
\**********************************************************************************************************************/
Address.prototype.clean =function() {
   var boolSuccess =true;

   //strip leading and trailing spaces
   this.strAddressee =trim(this.strAddressee);
   this.strBizName =trim(this.strBizName);
   this.strAddr1 =trim(this.strAddr1);
   this.strAddr2 =trim(this.strAddr2);
   this.strCity =trim(this.strCity);
   this.strRegion =trim(this.strRegion);
   this.strPostalCode =trim(this.strPostalCode);
   this.strCountry =trim(this.strCountry);
   this.charAddressType =trim(this.charAddressType);

   //strip all punctuation from all strings, except - from postal code.
   if(this.strAddressee) { this.strAddressee ="" +this.strAddressee.replace( /[!-\/,:-@,\[-`,\{-~]/g, " "); }
   if(this.strBizName) { this.strBizName ="" +this.strBizName.replace( /[!-\/,:-@,\[-`,\{-~]/g," "); }
   if(this.strAddr1) { this.strAddr1 ="" +this.strAddr1.replace( /[!-\/,:-@,\[-`,\{-~]/g," "); }
   if(this.strAddr2) { this.strAddr2 ="" +this.strAddr2.replace( /[!-\/,:-@,\[-`,\{-~]/g," "); }
   if(this.strCity) { this.strCity ="" +this.strCity.replace( /[!-\/,:-@,\[-`,\{-~]/g," "); }
   if(this.strRegion) { this.strRegion ="" +this.strRegion.replace( /[!-\/,:-@,\[-`,\{-~]/g," "); }
   if(this.strPostalCode) { this.strPostalCode ="" +this.strPostalCode.replace( /[!-\,,.-\/,:-@,\[-`,\{-~]/g,""); }
   if(this.strCountry) { this.strCountry ="" +this.strCountry.replace( /[!-\/,:-@,\[-`,\{-~]/g," "); }
   if(this.strAddressee) { this.strAddressee ="" +this.strAddressee.replace( /[!-\/,:-@,\[-`,\{-~]/g," "); }

   return boolSuccess;
}






/***********************************************************************************************************************
| serialize
| Collapse data into a | delimited string.
| return: serialization string
\**********************************************************************************************************************/
Address.prototype.serialize =function() {
   var strSerialized ="";

   this.clean();

   strSerialized += "|" +this.strAddressee +"|";      //field 1
   strSerialized += "|" +this.strBizName +"|";        //field 2
   strSerialized += "|" +this.strAddr1 +"|";          //field 3
   strSerialized += "|" +this.strAddr2 +"|";          //field 4
   strSerialized += "|" +this.strCity +"|";           //field 5
   strSerialized += "|" +this.strRegion +"|";         //field 6
   strSerialized += "|" +this.strPostalCode +"|";     //field 7
   strSerialized += "|" +this.strCountry +"|";        //field 8
   strSerialized += "|" +this.charAddressType +"|";   //field 9

   return strSerialized;
}






/***********************************************************************************************************************
| deserialize
| Expand data from a | delimited string.
| return: boolean - successful?
\**********************************************************************************************************************/
Address.prototype.deserialize =function(strSerialized) {
   var boolSuccess =true;

   try {
      if(strSerialized.indexOf("|") >= 0) {
         var arrMembers =strSerialized.split("||");

         this.strAddressee =("" +arrMembers[0]).substr(1);
         this.strBizName =arrMembers[1];
         this.strAddr1 =arrMembers[2];
         this.strAddr2 =arrMembers[3];
         this.strCity =arrMembers[4];
         this.strRegion =arrMembers[5];
         this.strPostalCode =arrMembers[6];
         this.strCountry =arrMembers[7];
         this.charAddressType =("" +arrMembers[8]).substr(0,("" +arrMembers[8]).length -1);
      }
   } catch(err) { boolSuccess =false; }

   return boolSuccess;
}






/***********************************************************************************************************************
| ACCESSORS
\**********************************************************************************************************************/


/***********************************************************************************************************************
| MUTATORS
\**********************************************************************************************************************/







try { checkIfLastToLoad(); } catch(error) {;}
