function formatPhone(num) {
  //NXX-NXX-XXXX
  //N=[2-9]
  //X=[0-9]
  num = num.toString().replace(/[^0-9]/g, "");
  if (num[0] == "1") {
    num = num.substr(1);
  }
  if (num.length >= 3) {
    NPA = num.substr(0, 3)
    COCode = num.substr(3, 3)
    lineNumber = num.substr(6, 4)
    N = "[2-9]"
    X = "[0-9]"
    Y = "0"
    NXX = N + X + X
    N11 = N + "11"  //These 8 ERCs, called service codes, are not used as area codes.
    N00 = N + Y + Y  //N00 NPA Codes Various uses.
    N9X = N + "9" + X  //The 80 codes in this format, called expansion codes, have been reserved for use during the period when the current 10-digit NANP number format undergoes expansion.
    _37X = "37" + X //Two blocks of 10 codes each have been set aside by the INC for unanticipated purposes where it may be important to have a full range of 10 contiguous codes available.*/
    _555 = "555"  // Information services
    _96X = "96" + X //Two blocks of 10 codes each have been set aside by the INC for unanticipated purposes where it may be important to have a full range of 10 contiguous codes available.*/
    NPAMatch = "(" + N00 + "|" + N11 + "|" + N9X + "|" + _37X + "|" + _555 + "|" + _96X + ")";
//    if (!NPA.match(new Regexp(NXX)) || NPA.match(new Regexp(NPAMatch)) || !COCode.match(new Regexp(NXX))) {
//      alert("Your phone number doesn't appear to be a valid number or is in an area we cannot provide service.")
//    }
    if (num.length >= 6) {
      if (num.length > 10) {
        return "(" + NPA + ") " + COCode + "-" + lineNumber + " x" + num.substr(10);
      } else {
        return "(" + NPA + ") " + COCode + "-" + lineNumber;
      }
    } else {
      return "(" + NPA + ") " + COCode
    }
  } else {
    return num
  }
}

/*
http://www.nanpa.com/area_codes/
More about area codes...
The format of an area code is NXX, where N is any digit 2 through 9 and X is any digit 0 through 9. Initially, the middle digit of an area code had to be "0" or "1". When this restriction was removed in 1995, additional area code combinations became available. There are 800 possible combinations associated with the NXX format. Some of these combinations, however, are not available or have been reserved for special purposes
Among them are the following:
Easily Recognizable Codes   When the second and third digits of an area code are the same, that code is called an easily recognizable code (ERC). ERCs designate special services; e.g., 888 for toll-free service.
N11   These 8 ERCs, called service codes, are not used as area codes.
N9X   The 80 codes in this format, called expansion codes, have been reserved for use during the period when the current 10-digit NANP number format undergoes expansion.
37X and 96X   Two blocks of 10 codes each have been set aside by the INC for unanticipated purposes where it may be important to have a full range of 10 contiguous codes available.
*/

function cleanKeyEvent(event) {
  if(
    event.keyCode == 8 ||
    event.altKey ||
    event.ctrlKey
    ) return true;
  key = String.fromCharCode(event.keyCode); 
  if(isNaN(key)) return false;
  return true; 
}


function ToolTip(tooltip) {
  this.object = tooltip;
  this.arrow = this.object.descendants()[0];
  this.parent = this.object.ancestors()[0];

  this.show = function (which) {
    if(which == undefined) {
      which = 'down';
    }
    
    this.object.show();
    offset = this._calculateOffset()
    this.arrow.style.left  = (parseInt(this.object.style.width)-25) + "px";
    this.object.style.left = ((offset.left-parseInt(this.object.style.width))+19) + "px";
    if (which == 'down') {
      this.object.style.top = (offset.top + (parseInt(this.arrow.style.height) || 12)) + "px";
    } else {
      this.arrow.style.top  = (parseInt(this.object.offsetHeight) - 2) + "px";
      this.object.style.top = (offset.top - (parseInt(this.object.offsetHeight)) - 21) + "px";
    }
  }

  this.hide = function () {
    this.object.hide() 
  }

  this._calculateOffset = function () {
    if(this.parent.offsetParent.nodeName.toLowerCase() == "body") {
      return {
        "left": this.parent.offsetLeft,
        "top": this.parent.offsetTop
      }
    } // firefox offset


    // ie 6 offset
    src = event.srcElement
    if(src.nodeName.toLowerCase() == "img") {
//      +---------
//      |        x
//      |
//      |
//      |y
//      
      if(event.offsetX > 8) {
        x = event.clientX-(event.offsetX == 16 ? 16 : event.offsetX%16)-3
      } else {
        x = event.clientX+(-2-(event.offsetX%16))
      }

      if(event.offsetY > 8) {
        y = event.clientY-(event.offsetY == 16 ? 16 : event.offsetY%16)+3
      } else {
        y = event.clientY+(4-(event.offsetY%16))
      }
      if (isNaN(x)) x = event.clientX
      if (isNaN(y)) y = event.clientY
      // these are failsafe's they're ugly but sane

      if(ver = navigator.appVersion.match(/MSIE\s([5678]\.\d)/)[1])
        switch(ver) {
          case '6.0':
            y = y
            break;
          case '7.0':
            // y += 12
            break;
        }
    }
    return {"left":x, "top":y}
  }
}
