/***********************************************************************************************************************
| object/Contact.js
| Wrapper for contact information.
***********************************************************************************************************************/




/***********************************************************************************************************************
| CONSTRUCTOR - Contact
\**********************************************************************************************************************/
function Contact(strId) {
   this.className ="Contact";

   this.strId =strId;
   if(!this.strId) { this.strId =-1; }
}



/***********************************************************************************************************************
| CONSTRUCTOR - Phone
\**********************************************************************************************************************/
function Phone(strPhone, strId) {
   this.className ="Phone";

   this.strId =strId;
   this.strPhone =this.parsePhone(strPhone);
   this.strPhoneFormatted =this.formatPhone(this.strPhone);
   if(!this.strPhone) { this.strPhone =""; }
   if(!this.strPhoneFormatted) { this.strPhoneFormatted =""; }
}
Phone.prototype =new Contact;
Phone.prototype.parsePhone =function(strPhone) {
   var strParsed ="";

   if(strPhone) { strParsed =strPhone.replace(/\D*\s*/gi,""); }
   if(strPhone && strPhone.length < 10) { strParsed =""; }

   return strParsed;
}
Phone.prototype.formatPhone =function(strPhone) {
   var strFormatted ="";

   if(strPhone) {
      strPhone +="";       //cast to string
      strFormatted ="(" +strPhone.substr(0,3) +") " +strPhone.substr(3,3) +"-" +strPhone.substr(6,4);
   }

   return strFormatted;
}
Phone.prototype.setPhone =function(strPhone) {
   var boolSuccess =false;

   if(strPhone) {
      strPhone =this.parsePhone(strPhone);
      if(strPhone) {
         this.strPhone =strPhone;
         this.strPhoneFormatted ="(" +this.strPhone.substr(0,3) +") " +this.strPhone.substr(4,3) +"-" +this.strPhone.substr(7,4);
         boolSuccess =true;
      }
   }

   return boolSuccess;
}
Phone.prototype.isValid =function() {
   var boolValid =this.strPhoneFormatted != "" ? true : false;

   return boolValid;
}
Phone.prototype.sanityCheck =function() {
   var strDiagnosis ="";

   if(!this.strPhone) { strDiagnosis ="missing~Phone Number|"; }
   if(this.strPhone && !this.strPhoneFormatted) { strDiagnosis ="error~Phone number present but no formatted phone number.|"; }

   if(strDiagnosis == "") { strDiagnosis ="sane"; }
   else { strDiagnosis ="className~Phone|id~" +this.strId +"|" +strDiagnosis; }

   return strDiagnosis;
}

/***********************************************************************************************************************
| serialize
| Collapse data into a | delimited string.
| return: serialization string
\**********************************************************************************************************************/
Phone.prototype.serialize =function() {
   var strSerialized ="";

   strSerialized += "|" +this.strId +"|";      //field 1
   strSerialized += "|" +this.strPhone +"|";        //field 2

   return strSerialized;
}

/***********************************************************************************************************************
| deserialize
| Collapse data into a | delimited string.
| return: serialization string
\**********************************************************************************************************************/
Phone.prototype.deserialize =function(strSerialized) {
   var boolSuccess =true;

   try {
      if(strSerialized.indexOf("|") >= 0) {
         var arrMembers =strSerialized.split("||");

         this.strId =("" +arrMembers[0]).substr(1);
         this.setPhone(("" +arrMembers[1]).substr(0,("" +arrMembers[1]).length -1));
      }
   } catch(err) { boolSuccess =false; }

   return boolSuccess;
}



/***********************************************************************************************************************
| CONSTRUCTOR - Email
\**********************************************************************************************************************/
function Email(strEmail, strId) {
   this.className ="Email";

   this.strId =strId;
   this.strEmail =this.parseEmail(strEmail);
   if(!this.strEmail) { this.strEmail =""; }
}
Email.prototype =new Contact;
Email.prototype.parseEmail =function(strEmail) {
   var strParsed ="";
   var regex, undefined;

   if(strEmail) {
      regex =/^[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$/;
      strParsed =regex.exec(strEmail);
      if(strParsed == null) { strParsed =undefined; }
   }

   return strParsed;
}
Email.prototype.setEmail =function(strEmail) {
   var boolSuccess =false;

   if(strEmail) {
      strEmail =this.parseEmail(strEmail);
      if(strEmail) {
         this.strEmail =strEmail;
         boolSuccess =true;
      }
   }

   return boolSuccess;
}
Email.prototype.isValid =function() {
   var boolValid =this.strEmail != "" ? true : false;

   return boolValid;
}
Email.prototype.sanityCheck =function() {
   var strDiagnosis ="";

   if(!this.strEmail) { strDiagnosis ="missing~Email Address|"; }

   if(strDiagnosis == "") { strDiagnosis ="sane"; }
   else { strDiagnosis ="className~Email|id~" +this.strId +"|" +strDiagnosis; }

   return strDiagnosis;
}

/***********************************************************************************************************************
| serialize
| Collapse data into a | delimited string.
| return: serialization string
\**********************************************************************************************************************/
Email.prototype.serialize =function() {
   var strSerialized ="";

   strSerialized += "|" +this.strId +"|";      //field 1
   strSerialized += "|" +this.strEmail +"|";        //field 2

   return strSerialized;
}

/***********************************************************************************************************************
| deserialize
| Collapse data into a | delimited string.
| return: serialization string
\**********************************************************************************************************************/
Email.prototype.deserialize =function(strSerialized) {
   var boolSuccess =true;

   try {
      if(strSerialized.indexOf("|") >= 0) {
         var arrMembers =strSerialized.split("||");

         this.strId =("" +arrMembers[0]).substr(1);
         this.strEmail =("" +arrMembers[1]).substr(0,("" +arrMembers[1]).length -1);
      }
   } catch(err) { boolSuccess =false; }

   return boolSuccess;
}





/***********************************************************************************************************************
| sanityCheck
| Performs a sequence of checks on vital data to ensure all values are legal.
| returns: either "sane" or a '|\n' delimited list of sanity check failures.
\**********************************************************************************************************************/
Contact.prototype.sanityCheck =function() {
   var strDiagnosis ="";

   if(strDiagnosis == "") { strDiagnosis ="sane"; }

   return strDiagnosis;
}





/***********************************************************************************************************************
| serialize
| Collapse data into a | delimited string.
| return: serialization string
\**********************************************************************************************************************/
Contact.prototype.serialize =function() {
   var strSerialized ="";

   return strSerialized;
}





/***********************************************************************************************************************
| toString
| Debugging tool; shows all members of an object and of any child objects that share this toString function.
| boolShowChildren: show members of child objects? (default=false)
| strLabel: the label to show for the object in the output.
| intDepth: the depth of indentation for the tree (for recurvsive calls only)
\**********************************************************************************************************************/
Contact.prototype.toString =function(boolShowChildren, boolShowFunctions, strLabel, intDepth) {
   var i, j, strFieldName;
   var strOutput ="";
   var strTypeIndent ="-";
   var strMemberIndent ="---";

   var strArrayMembers ="";

   var arrUndefined =new Array();
   var arrPrimitives =new Array();
   var arrObjects =new Array();
   var arrArrays =new Array();
   var arrFunctions =new Array();

   if(!intDepth) { intDepth =0; }
   if(!strLabel) { strLabel ="this"; }

   for(i =0; i < intDepth-1; i++) {
      strTypeIndent +="---";
      strMemberIndent +="------";
   }

   if(intDepth > 0) {
      strTypeIndent +="--|";
      strMemberIndent +="|----";
   }

   for(i in this) {
      if(typeof this[i] == "function") { arrFunctions[arrFunctions.length] =i +"( )"; }
      else if(typeof this[i] == "object") {
         if(this[i] instanceof Array) {
            j =0;
            strArrayMembers ="";
            if(this[i].length > 0 && this[i][0]) { j =this[i].length; }
            else { strArrayMembers =", hashed"; for(strFieldName in this[i]) { j++; strArrayMembers +=", " +strFieldName} }
            if(j == 0) { strArrayMembers =""; }
            arrArrays[arrArrays.length] =i +" [" +j +strArrayMembers +"]";
         }
         else {
            if(this[i] && this[i].className) { arrObjects[arrObjects.length] =i +" ......class: " +this[i].className; }
            else { arrObjects[arrObjects.length] =i +" ......object"; }
            if(this[i] && boolShowChildren) { arrObjects[arrObjects.length -1] +="<br>\n" +this[i].toString(boolShowChildren, boolShowFunctions, i, intDepth +1); }
         }
      }
      else if(typeof this[i] == "undefined") { arrUndefined[arrUndefined.length] =i; }
      else { arrPrimitives[arrPrimitives.length] =i +" = " +this[i] + " ......type: " +(typeof this[i]); }
   }

   if(!arrUndefined[0]) { arrUndefined[0] ="___"; }
   else { arrUndefined.sort(); }
   if(!arrPrimitives[0]) { arrPrimitives[0] ="___"; }
   else { arrPrimitives.sort(); }
   if(!arrObjects[0]) { arrObjects[0] ="___"; }
   else { arrObjects.sort(); }
   if(!arrArrays[0]) { arrArrays[0] ="___"; }
   else { arrArrays.sort(); }
   if(!arrFunctions[0]) { arrFunctions[0] ="___"; }
   else { arrFunctions.sort(); }

   strOutput ="|" +strTypeIndent +strLabel +".Undefined<br>\n|" +strMemberIndent +" " +arrUndefined.join("<br>\n|" +strMemberIndent +" ") +
              "<br>\n|" +strTypeIndent +strLabel +".Primitives<br>\n|" +strMemberIndent +" " +arrPrimitives.join("<br>\n|" +strMemberIndent +" ") +
              "<br>\n|" +strTypeIndent +strLabel +".Objects<br>\n|" +strMemberIndent +" " +arrObjects.join("<br>\n|" +strMemberIndent +" ") +
              "<br>\n|" +strTypeIndent +strLabel +".Arrays<br>\n|" +strMemberIndent +" " +arrArrays.join("<br>\n|" +strMemberIndent +" ");
   if(boolShowFunctions) { strOutput +="<br>\n|" +strTypeIndent +strLabel +".Functions<br>\n|" +strMemberIndent +" " +arrFunctions.join("<br>\n|" +strMemberIndent +" "); }

   return strOutput;
}



/***********************************************************************************************************************
| ACCESSORS
\**********************************************************************************************************************/


/***********************************************************************************************************************
| MUTATORS
\**********************************************************************************************************************/






try { checkIfLastToLoad(); } catch(error) {;}
