//  Prototip 2.0.5 - 28-10-2008
//  Copyright (c) 2008 Nick Stakenburg (http://www.nickstakenburg.com)
//
//  Licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License
//  http://creativecommons.org/licenses/by-nc-nd/3.0/

//  More information on this project:
//  http://www.nickstakenburg.com/projects/prototip2/

var Prototip = {
  Version: '2.0.5'
};

var Tips = {
  options: {
    images: '../images/prototip/', // image path, can be relative to this file or an absolute url
    zIndex: 6000                   // raise if required
  }
};

Prototip.Styles = {
  // The default style every other style will inherit from.
  // Used when no style is set through the options on a tooltip.
  'default': {
    border: 6,
    borderColor: '#c7c7c7',
    className: 'default',
    closeButton: false,
    hideAfter: false,
    hideOn: 'mouseleave',
    hook: false,
	//images: 'styles/creamy/',    // Example: different images. An absolute url or relative to the images url defined above.
    radius: 6,
	showOn: 'mousemove',
    stem: {
      //position: 'topLeft',       // Example: optional default stem position, this will also enable the stem
      height: 12,
      width: 15
    }
  },

  'protoblue': {
    className: 'protoblue',
    border: 6,
    borderColor: '#116497',
    radius: 6,
    stem: { height: 12, width: 15 }
  },

  'darkgrey': {
    className: 'darkgrey',
    border: 6,
    borderColor: '#363636',
    radius: 6,
    stem: { height: 12, width: 15 }
  },

  'creamy': {
    className: 'creamy',
    border: 6,
    borderColor: '#ebe4b4',
    radius: 6,
    stem: { height: 12, width: 15 }
  },

  'protogrey': {
    className: 'protogrey',
    border: 6,
    borderColor: '#606060',
    radius: 6,
    stem: { height: 12, width: 15 }
  }
};

Object.extend(Prototip, {
  REQUIRED_Prototype: "1.6.0.3",
  start: function() {
    this.require("Prototype");
    if (/^(https?:\/\/|\/)/.test(Tips.options.images)) {
      Tips.images = Tips.options.images
    } else {
      var A = /prototip(?:-[\w\d.]+)?\.js(.*)/;
      Tips.images = (($$("head script[src]").find(function(B) {
        return B.src.match(A)
      }) || {}).src || "").replace(A, "") + Tips.options.images
    }
    if (Prototype.Browser.IE && !document.namespaces.v) {
      document.namespaces.add("v", "urn:schemas-microsoft-com:vml");
      document.observe("dom:loaded",
      function() {
        document.createStyleSheet().addRule("v\\:*", "behavior: url(#default#VML);")
      })
    }
    Tips.initialize();
    Element.observe(window, "unload", this.unload)
  },
  require: function(A) {
    if ((typeof window[A] == "undefined") || (this.convertVersionString(window[A].Version) < this.convertVersionString(this["REQUIRED_" + A]))) {
      throw ("Prototip requires " + A + " >= " + this["REQUIRED_" + A]);
    }
  },
  convertVersionString: function(A) {
    var B = A.replace(/_.*|\./g, "");
    B = parseInt(B + "0".times(4 - B.length));
    return A.indexOf("_") > -1 ? B - 1 : B
  },
  _captureTroubleElements: $w("input textarea"),
  capture: function(A) {
    if (Prototype.Browser.IE) {
      return A
    }
    A = A.wrap(function(E, D) {
      var B = Object.isElement(this) ? this: this.element,
      C = D.relatedTarget;
      while (C && C != B) {
        try {
          C = C.parentNode
        } catch(F) {
          C = B
        }
      }
      if (C == B) {
        return
      }
      E(D)
    });
    return A
  },
  toggleInt: function(A) {
    return (A > 0) ? ( - 1 * A) : (A).abs()
  },
  unload: function() {
    Tips.removeAll()
  }
});
Object.extend(Tips, {
  tips: [],
  visible: [],
  initialize: function() {
    this.zIndexTop = this.zIndex
  },
  useEvent: (function(A) {
    return {
      mouseover: (A ? "mouseenter": "mouseover"),
      mouseout: (A ? "mouseleave": "mouseout"),
      mouseenter: (A ? "mouseenter": "mouseover"),
      mouseleave: (A ? "mouseleave": "mouseout")
    }
  })(Prototype.Browser.IE),
  specialEvent: {
    mouseover: "mouseover",
    mouseout: "mouseout",
    mouseenter: "mouseover",
    mouseleave: "mouseout"
  },
  _inverse: {
    left: "right",
    right: "left",
    top: "bottom",
    bottom: "top",
    middle: "middle",
    horizontal: "vertical",
    vertical: "horizontal"
  },
  _stemTranslation: {
    width: "horizontal",
    height: "vertical"
  },
  inverseStem: function(A) {
    return !! arguments[1] ? this._inverse[A] : A
  },
  fixIE: (function(B) {
    var A = new RegExp("MSIE ([\\d.]+)").exec(B);
    return A ? (parseFloat(A[1]) < 7) : false
  })(navigator.userAgent),
  WebKit419: (Prototype.Browser.WebKit && !document.evaluate),
  add: function(A) {
    this.tips.push(A)
  },
  remove: function(A) {
    var B = this.tips.find(function(C) {
      return C.element == $(A)
    });
    if (B) {
      B.deactivate();
      if (B.tooltip) {
        B.wrapper.remove();
        if (Tips.fixIE) {
          B.iframeShim.remove()
        }
      }
      this.tips = this.tips.without(B)
    }
    A.prototip = null
  },
  removeAll: function() {
    this.tips.each(function(A) {
      this.remove(A.element)
    }.bind(this))
  },
  raise: function(C) {
    if (C == this._highest) {
      return
    }
    if (this.visible.length === 0) {
      this.zIndexTop = this.options.zIndex;
      for (var B = 0,
      A = this.tips.length; B < A; B++) {
        this.tips[B].wrapper.setStyle({
          zIndex: this.options.zIndex
        })
      }
    }
    C.wrapper.setStyle({
      zIndex: this.zIndexTop++
    });
    if (C.loader) {
      C.loader.setStyle({
        zIndex: this.zIndexTop
      })
    }
    this._highest = C
  },
  addVisibile: function(A) {
    this.removeVisible(A);
    this.visible.push(A)
  },
  removeVisible: function(A) {
    this.visible = this.visible.without(A)
  },
  hideAll: function() {
    Tips.visible.invoke("hide")
  },
  hook: function(B, F) {
    B = $(B),
    F = $(F);
    var K = Object.extend({
      offset: {
        x: 0,
        y: 0
      },
      position: false
    },
    arguments[2] || {});
    var D = K.mouse || F.cumulativeOffset();
    D.left += K.offset.x;
    D.top += K.offset.y;
    var C = K.mouse ? [0, 0] : F.cumulativeScrollOffset(),
    A = document.viewport.getScrollOffsets(),
    G = K.mouse ? "mouseHook": "target";
    D.left += ( - 1 * (C[0] - A[0]));
    D.top += ( - 1 * (C[1] - A[1]));
    if (K.mouse) {
      var E = [0, 0];
      E.width = 0;
      E.height = 0
    }
    var I = {
      element: B.getDimensions()
    },
    J = {
      element: Object.clone(D)
    };
    I[G] = K.mouse ? E: F.getDimensions();
    J[G] = Object.clone(D);
    for (var H in J) {
      switch (K[H]) {
      case "topRight":
      case "rightTop":
        J[H].left += I[H].width;
        break;
      case "topMiddle":
        J[H].left += (I[H].width / 2);
        break;
      case "rightMiddle":
        J[H].left += I[H].width;
        J[H].top += (I[H].height / 2);
        break;
      case "bottomLeft":
      case "leftBottom":
        J[H].top += I[H].height;
        break;
      case "bottomRight":
      case "rightBottom":
        J[H].left += I[H].width;
        J[H].top += I[H].height;
        break;
      case "bottomMiddle":
        J[H].left += (I[H].width / 2);
        J[H].top += I[H].height;
        break;
      case "leftMiddle":
        J[H].top += (I[H].height / 2);
        break
      }
    }
    D.left += -1 * (J.element.left - J[G].left);
    D.top += -1 * (J.element.top - J[G].top);
    if (K.position) {
      B.setStyle({
        left: D.left + "px",
        top: D.top + "px"
      })
    }
    return D
  }
});
Tips.initialize();
var Tip = Class.create({
  initialize: function(C, E) {
    this.element = $(C);
    if (!this.element) {
      throw ("Prototip: Element not available, cannot create a tooltip.");
      return
    }
    Tips.remove(this.element);
    var A = (Object.isString(E) || Object.isElement(E)),
    B = A ? arguments[2] || [] : E;
    this.content = A ? E: null;
    if (B.style) {
      B = Object.extend(Object.clone(Prototip.Styles[B.style]), B)
    }
    this.options = Object.extend(Object.extend({
      ajax: false,
      border: 0,
      borderColor: "#000000",
      radius: 0,
      className: Tips.options.className,
      closeButton: Tips.options.closeButtons,
      delay: !(B.showOn && B.showOn == "click") ? 0.14 : false,
      hideAfter: false,
      hideOn: "mouseleave",
      hideOthers: false,
      hook: B.hook,
      offset: B.hook ? {
        x: 0,
        y: 0
      }: {
        x: 16,
        y: 16
      },
      fixed: (B.hook && !B.hook.mouse) ? true: false,
      showOn: "mousemove",
      stem: false,
      style: "default",
      target: this.element,
      title: false,
      viewport: (B.hook && !B.hook.mouse) ? false: true,
      width: false
    },
    Prototip.Styles["default"]), B);
    this.target = $(this.options.target);
    this.radius = this.options.radius;
    this.border = (this.radius > this.options.border) ? this.radius: this.options.border;
    if (this.options.images) {
      this.images = this.options.images.include("://") ? this.options.images: Tips.images + this.options.images
    } else {
      this.images = Tips.images + "styles/" + (this.options.style || "") + "/"
    }
    if (!this.images.endsWith("/")) {
      this.images += "/"
    }
    if (Object.isString(this.options.stem)) {
      this.options.stem = {
        position: this.options.stem
      }
    }
    if (this.options.stem.position) {
      this.options.stem = Object.extend(Object.clone(Prototip.Styles[this.options.style].stem) || {},
      this.options.stem);
      this.options.stem.position = [this.options.stem.position.match(/[a-z]+/)[0].toLowerCase(), this.options.stem.position.match(/[A-Z][a-z]+/)[0].toLowerCase()];
      this.options.stem.orientation = ["left", "right"].member(this.options.stem.position[0]) ? "horizontal": "vertical";
      this.stemInverse = {
        horizontal: false,
        vertical: false
      }
    }
    if (this.options.ajax) {
      this.options.ajax.options = Object.extend({
        onComplete: Prototype.emptyFunction
      },
      this.options.ajax.options || {})
    }
    this.useEvent = $w("area input").member(this.element.tagName.toLowerCase()) ? Tips.specialEvent: Tips.useEvent;
    if (this.options.hook.mouse) {
      var D = this.options.hook.tip.match(/[a-z]+/)[0].toLowerCase();
      this.mouseHook = Tips._inverse[D] + Tips._inverse[this.options.hook.tip.match(/[A-Z][a-z]+/)[0].toLowerCase()].capitalize()
    }
    this.fixSafari2 = (Tips.WebKit419 && this.radius);
    this.setup();
    Tips.add(this);
    this.activate();
    Prototip.extend(this)
  },
  setup: function() {
    this.wrapper = new Element("div", {
      className: "prototip"
    }).setStyle({
      zIndex: Tips.options.zIndex
    });
    if (this.fixSafari2) {
      this.wrapper.hide = function() {
        this.setStyle("left:-9500px;top:-9500px;visibility:hidden;");
        return this
      };
      this.wrapper.show = function() {
        this.setStyle("visibility:visible");
        return this
      };
      this.wrapper.visible = function() {
        return (this.getStyle("visibility") == "visible" && parseFloat(this.getStyle("top").replace("px", "")) > -9500)
      }
    }
    this.wrapper.hide();
    if (Tips.fixIE) {
      this.iframeShim = new Element("iframe", {
        className: "iframeShim",
        src: "javascript:false;",
        frameBorder: 0
      }).setStyle({
        display: "none",
        zIndex: Tips.options.zIndex - 1,
        opacity: 0
      })
    }
    if (this.options.ajax) {
      this.showDelayed = this.showDelayed.wrap(this.ajaxShow)
    }
    this.tip = new Element("div", {
      className: "content"
    });
    this.title = new Element("div", {
      className: "title"
    }).hide();
    if (this.options.closeButton || (this.options.hideOn.element && this.options.hideOn.element == "closeButton")) {
      this.closeButton = new Element("div", {
        className: "close"
      }).setPngBackground(this.images + "close.png")
    }
  },
  build: function() {
    if (document.loaded) {
      this._build();
      this._isBuilding = true;
      return true
    } else {
      if (!this._isBuilding) {
        document.observe("dom:loaded", this._build);
        return false
      }
    }
  },
  _build: function() {
    $(document.body).insert(this.wrapper);
    if (Tips.fixIE) {
      $(document.body).insert(this.iframeShim)
    }
    if (this.options.ajax) {
      $(document.body).insert(this.loader = new Element("div", {
        className: "prototipLoader"
      }).setPngBackground(this.images + "loader.gif").hide())
    }
    var G = "wrapper";
    if (this.options.stem.position) {
      this.stem = new Element("div", {
        className: "prototip_Stem"
      }).setStyle({
        height: this.options.stem[this.options.stem.orientation == "vertical" ? "height": "width"] + "px"
      });
      var B = this.options.stem.orientation == "horizontal";
      this[G].insert(this.stemWrapper = new Element("div", {
        className: "prototip_StemWrapper clearfix"
      }).insert(this.stemBox = new Element("div", {
        className: "prototip_StemBox clearfix"
      })));
      this.stem.insert(this.stemImage = new Element("div", {
        className: "prototip_StemImage"
      }).setStyle({
        height: this.options.stem[B ? "width": "height"] + "px",
        width: this.options.stem[B ? "height": "width"] + "px"
      }));
      if (Tips.fixIE && !this.options.stem.position[1].toUpperCase().include("MIDDLE")) {
        this.stemImage.setStyle({
          display: "inline"
        })
      }
      G = "stemBox"
    }
    if (this.border) {
      var D = this.border,
      F;
      this[G].insert(this.borderFrame = new Element("ul", {
        className: "borderFrame"
      }).insert(this.borderTop = new Element("li", {
        className: "borderTop borderRow"
      }).setStyle("height: " + D + "px").insert(new Element("div", {
        className: "prototip_CornerWrapper prototip_CornerWrapperTopLeft"
      }).insert(new Element("div", {
        className: "prototip_Corner"
      }))).insert(F = new Element("div", {
        className: "prototip_BetweenCorners"
      }).setStyle({
        height: D + "px"
      }).insert(new Element("div", {
        className: "prototip_Between"
      }).setStyle({
        margin: "0 " + D + "px",
        height: D + "px"
      }))).insert(new Element("div", {
        className: "prototip_CornerWrapper prototip_CornerWrapperTopRight"
      }).insert(new Element("div", {
        className: "prototip_Corner"
      })))).insert(this.borderMiddle = new Element("li", {
        className: "borderMiddle borderRow"
      }).insert(this.borderCenter = new Element("div", {
        className: "borderCenter"
      }).setStyle("padding: 0 " + D + "px"))).insert(this.borderBottom = new Element("li", {
        className: "borderBottom borderRow"
      }).setStyle("height: " + D + "px").insert(new Element("div", {
        className: "prototip_CornerWrapper prototip_CornerWrapperBottomLeft"
      }).insert(new Element("div", {
        className: "prototip_Corner"
      }))).insert(F.cloneNode(true)).insert(new Element("div", {
        className: "prototip_CornerWrapper prototip_CornerWrapperBottomRight"
      }).insert(new Element("div", {
        className: "prototip_Corner"
      })))));
      G = "borderCenter";
      var C = this.borderFrame.select(".prototip_Corner");
      $w("tl tr bl br").each(function(I, H) {
        if (this.radius > 0) {
          Prototip.createCorner(C[H], I, {
            backgroundColor: this.options.borderColor,
            border: D,
            radius: this.options.radius
          })
        } else {
          C[H].addClassName("prototip_Fill")
        }
        C[H].setStyle({
          width: D + "px",
          height: D + "px"
        }).addClassName("prototip_Corner" + I.capitalize())
      }.bind(this));
      this.borderFrame.select(".prototip_Between", ".borderMiddle", ".prototip_Fill").invoke("setStyle", {
        backgroundColor: this.options.borderColor
      })
    }
    this[G].insert(this.tooltip = new Element("div", {
      className: "tooltip " + this.options.className
    }).insert(this.toolbar = new Element("div", {
      className: "toolbar"
    }).insert(this.title)));
    if (this.options.width) {
      var E = this.options.width;
      if (Object.isNumber(E)) {
        E += "px"
      }
      this.tooltip.setStyle("width:" + E)
    }
    if (this.stem) {
      var A = {};
      A[this.options.stem.orientation == "horizontal" ? "top": "bottom"] = this.stem;
      this.wrapper.insert(A);
      this.positionStem()
    }
    this.tooltip.insert(this.tip);
    if (!this.options.ajax) {
      this._update({
        title: this.options.title,
        content: this.content
      })
    }
  },
  _update: function(E) {
    var A = this.wrapper.getStyle("visibility");
    this.wrapper.setStyle("height:auto;width:auto;visibility:hidden").show();
    if (this.border) {
      this.borderTop.setStyle("height:0");
      this.borderTop.setStyle("height:0")
    }
    if (E.title) {
      this.title.show().update(E.title);
      this.toolbar.show()
    } else {
      if (!this.closeButton) {
        this.title.hide();
        this.toolbar.hide()
      }
    }
    if (Object.isElement(E.content)) {
      E.content.show()
    }
    if (Object.isString(E.content) || Object.isElement(E.content)) {
      this.tip.update(E.content)
    }
    this.tooltip.setStyle({
      width: this.tooltip.getWidth() + "px"
    });
    this.wrapper.setStyle("visibility:visible").show();
    this.tooltip.show();
    var C = this.tooltip.getDimensions(),
    B = {
      width: C.width + "px"
    },
    D = [this.wrapper];
    if (Tips.fixIE) {
      D.push(this.iframeShim)
    }
    if (this.closeButton) {
      this.title.show().insert({
        top: this.closeButton
      });
      this.toolbar.show()
    }
    if (E.title || this.closeButton) {
      this.toolbar.setStyle("width: 100%")
    }
    B.height = null;
    this.wrapper.setStyle({
      visibility: A
    });
    this.tip.addClassName("clearfix");
    if (E.title || this.closeButton) {
      this.title.addClassName("clearfix")
    }
    if (this.border) {
      this.borderTop.setStyle("height:" + this.border + "px");
      this.borderTop.setStyle("height:" + this.border + "px");
      B = "width: " + (C.width + 2 * this.border) + "px";
      D.push(this.borderFrame)
    }
    D.invoke("setStyle", B);
    if (this.stem) {
      this.positionStem();
      if (this.options.stem.orientation == "horizontal") {
        this.wrapper.setStyle({
          width: this.wrapper.getWidth() + this.options.stem.height + "px"
        })
      }
    }
    this.wrapper.hide()
  },
  activate: function() {
    this.eventShow = this.showDelayed.bindAsEventListener(this);
    this.eventHide = this.hide.bindAsEventListener(this);
    if (this.options.fixed && this.options.showOn == "mousemove") {
      this.options.showOn = "mouseover"
    }
    if (this.options.showOn == this.options.hideOn) {
      this.eventToggle = this.toggle.bindAsEventListener(this);
      this.element.observe(this.options.showOn, this.eventToggle)
    }
    if (this.closeButton) {
      this.closeButton.observe("mouseover",
      function(E) {
        E.setPngBackground(this.images + "close_hover.png")
      }.bind(this, this.closeButton)).observe("mouseout",
      function(E) {
        E.setPngBackground(this.images + "close.png")
      }.bind(this, this.closeButton))
    }
    var C = {
      element: this.eventToggle ? [] : [this.element],
      target: this.eventToggle ? [] : [this.target],
      tip: this.eventToggle ? [] : [this.wrapper],
      closeButton: [],
      none: []
    },
    A = this.options.hideOn.element;
    this.hideElement = A || (!this.options.hideOn ? "none": "element");
    this.hideTargets = C[this.hideElement];
    if (!this.hideTargets && A && Object.isString(A)) {
      this.hideTargets = this.tip.select(A)
    }
    var D = {
      mouseenter: "mouseover",
      mouseleave: "mouseout"
    };
    $w("show hide").each(function(H) {
      var G = H.capitalize(),
      F = (this.options[H + "On"].event || this.options[H + "On"]);
      this[H + "Action"] = F;
      if (["mouseenter", "mouseleave", "mouseover", "mouseout"].include(F)) {
        this[H + "Action"] = (this.useEvent[F] || F);
        this["event" + G] = Prototip.capture(this["event" + G])
      }
    }.bind(this));
    if (!this.eventToggle) {
      this.element.observe(this.options.showOn, this.eventShow)
    }
    if (this.hideTargets) {
      this.hideTargets.invoke("observe", this.hideAction, this.eventHide)
    }
    if (!this.options.fixed && this.options.showOn == "click") {
      this.eventPosition = this.position.bindAsEventListener(this);
      this.element.observe("mousemove", this.eventPosition)
    }
    this.buttonEvent = this.hide.wrap(function(G, F) {
      var E = F.findElement(".close");
      if (E) {
        E.blur();
        F.stop();
        G(F)
      }
    }).bindAsEventListener(this);
    if (this.closeButton || (this.options.hideOn && (this.options.hideOn.element == ".close"))) {
      this.wrapper.observe("click", this.buttonEvent)
    }
    if (this.options.showOn != "click" && (this.hideElement != "element")) {
      this.eventCheckDelay = Prototip.capture(function() {
        this.clearTimer("show")
      }).bindAsEventListener(this);
      this.element.observe(this.useEvent.mouseout, this.eventCheckDelay)
    }
    var B = [this.element, this.wrapper];
    this.activityEnter = Prototip.capture(function() {
      Tips.raise(this);
      this.cancelHideAfter()
    }).bindAsEventListener(this);
    this.activityLeave = Prototip.capture(this.hideAfter).bindAsEventListener(this);
    B.invoke("observe", this.useEvent.mouseover, this.activityEnter).invoke("observe", this.useEvent.mouseout, this.activityLeave);
    if (this.options.ajax && this.options.showOn != "click") {
      this.ajaxHideEvent = Prototip.capture(this.ajaxHide).bindAsEventListener(this);
      this.element.observe(this.useEvent.mouseout, this.ajaxHideEvent)
    }
  },
  deactivate: function() {
    if (this.options.showOn == this.options.hideOn) {
      this.element.stopObserving(this.options.showOn, this.eventToggle)
    } else {
      this.element.stopObserving(this.options.showOn, this.eventShow);
      if (this.hideTargets) {
        this.hideTargets.invoke("stopObserving")
      }
    }
    if (this.eventPosition) {
      this.element.stopObserving("mousemove", this.eventPosition)
    }
    if (this.eventCheckDelay) {
      this.element.stopObserving("mouseout", this.eventCheckDelay)
    }
    this.wrapper.stopObserving();
    this.element.stopObserving(this.useEvent.mouseover, this.activityEnter).stopObserving(this.useEvent.mouseout, this.activityLeave);
    if (this.ajaxHideEvent) {
      this.element.stopObserving(this.useEvent.mouseout, this.ajaxHideEvent)
    }
  },
  ajaxShow: function(C, B) {
    if (!this.tooltip) {
      if (!this.build()) {
        return
      }
    }
    this.position(B);
    if (this.ajaxContentLoading) {
      return
    } else {
      if (this.ajaxContentLoaded) {
        C(B);
        return
      }
    }
    this.ajaxContentLoading = true;
    var D = {
      fakePointer: {
        pointerX: Event.pointerX(B),
        pointerY: Event.pointerY(B)
      }
    };
    var A = Object.clone(this.options.ajax.options);
    A.onComplete = A.onComplete.wrap(function(F, E) {
      this._update({
        title: this.options.title,
        content: E.responseText
      });
      this.position(D); (function() {
        F(E);
        var G = (this.loader && this.loader.visible());
        if (this.loader) {
          this.clearTimer("loader");
          this.loader.remove();
          this.loader = null
        }
        if (G) {
          this.show()
        }
        this.ajaxContentLoaded = true;
        this.ajaxContentLoading = null
      }.bind(this)).delay(0.6)
    }.bind(this));
    this.loaderTimer = Element.show.delay(this.options.delay, this.loader);
    this.wrapper.hide();
    this.ajaxContentLoading = true;
    this.loader.show();
    this.ajaxTimer = (function() {
      new Ajax.Request(this.options.ajax.url, A)
    }.bind(this)).delay(this.options.delay);
    return false
  },
  ajaxHide: function() {
    this.clearTimer("loader")
  },
  showDelayed: function(A) {
    if (!this.tooltip) {
      if (!this.build()) {
        return
      }
    }
    this.position(A);
    if (this.wrapper.visible()) {
      return
    }
    this.clearTimer("show");
    this.showTimer = this.show.bind(this).delay(this.options.delay)
  },
  clearTimer: function(A) {
    if (this[A + "Timer"]) {
      clearTimeout(this[A + "Timer"])
    }
  },
  show: function() {
    if (this.wrapper.visible()) {
      return
    }
    if (Tips.fixIE) {
      this.iframeShim.show()
    }
    if (this.options.hideOthers) {
      Tips.hideAll()
    }
    Tips.addVisibile(this);
    this.tooltip.show();
    this.wrapper.show();
    if (this.stem) {
      this.stem.show()
    }

    // TXI hook
    Tips.activeTip = this;
    this.element.fire("prototip:shown")
  },
  hideAfter: function(A) {
    if (this.options.ajax) {
      if (this.loader && this.options.showOn != "click") {
        this.loader.hide()
      }
    }
    if (!this.options.hideAfter) {
      return
    }
    this.cancelHideAfter();
    this.hideAfterTimer = this.hide.bind(this).delay(this.options.hideAfter)
  },
  cancelHideAfter: function() {
    if (this.options.hideAfter) {
      this.clearTimer("hideAfter")
    }
  },
  hide: function() {
    this.clearTimer("show");
    this.clearTimer("loader");
    if (!this.wrapper.visible()) {
      return
    }
    this.afterHide()
  },
  afterHide: function() {
    if (Tips.fixIE) {
      this.iframeShim.hide()
    }
    if (this.loader) {
      this.loader.hide()
    }
    this.wrapper.hide(); (this.borderFrame || this.tooltip).show();
    Tips.removeVisible(this);
    this.element.fire("prototip:hidden")
  },
  toggle: function(A) {
    if (this.wrapper && this.wrapper.visible()) {
      this.hide(A)
    } else {
      this.showDelayed(A)
    }
  },
  positionStem: function() {
    var C = this.options.stem,
    B = arguments[0] || this.stemInverse,
    D = Tips.inverseStem(C.position[0], B[C.orientation]),
    F = Tips.inverseStem(C.position[1], B[Tips._inverse[C.orientation]]),
    A = this.radius || 0;
    this.stemImage.setPngBackground(this.images + D + F + ".png");
    if (C.orientation == "horizontal") {
      var E = (D == "left") ? C.height: 0;
      this.stemWrapper.setStyle("left: " + E + "px;");
      this.stemImage.setStyle({
        "float": D
      });
      this.stem.setStyle({
        left: 0,
        top: (F == "bottom" ? "100%": F == "middle" ? "50%": 0),
        marginTop: (F == "bottom" ? -1 * C.width: F == "middle" ? -0.5 * C.width: 0) + (F == "bottom" ? -1 * A: F == "top" ? A: 0) + "px"
      })
    } else {
      this.stemWrapper.setStyle(D == "top" ? "margin: 0; padding: " + C.height + "px 0 0 0;": "padding: 0; margin: 0 0 " + C.height + "px 0;");
      this.stem.setStyle(D == "top" ? "top: 0; bottom: auto;": "top: auto; bottom: 0;");
      this.stemImage.setStyle({
        margin: 0,
        "float": F != "middle" ? F: "none"
      });
      if (F == "middle") {
        this.stemImage.setStyle("margin: 0 auto;")
      } else {
        this.stemImage.setStyle("margin-" + F + ": " + A + "px;")
      }
      if (Tips.WebKit419) {
        if (D == "bottom") {
          this.stem.setStyle({
            position: "relative",
            clear: "both",
            top: "auto",
            bottom: "auto",
            "float": "left",
            width: "100%",
            margin: ( - 1 * C.height) + "px 0 0 0"
          });
          this.stem.style.display = "block"
        } else {
          this.stem.setStyle({
            position: "absolute",
            "float": "none",
            margin: 0
          })
        }
      }
    }
    this.stemInverse = B
  },
  position: function(B) {
    if (!this.tooltip) {
      if (!this.build()) {
        return
      }
    }
    Tips.raise(this);
    if (Tips.fixIE) {
      var A = this.wrapper.getDimensions();
      if (!this.iframeShimDimensions || this.iframeShimDimensions.height != A.height || this.iframeShimDimensions.width != A.width) {
        this.iframeShim.setStyle({
          width: A.width + "px",
          height: A.height + "px"
        })
      }
      this.iframeShimDimensions = A
    }
    if (this.options.hook) {
      var J, H;
      if (this.mouseHook) {
        var K = document.viewport.getScrollOffsets(),
        C = B.fakePointer || {};
        var G, I = 2;
        switch (this.mouseHook.toUpperCase()) {
        case "LEFTTOP":
        case "TOPLEFT":
          G = {
            x: 0 - I,
            y: 0 - I
          };
          break;
        case "TOPMIDDLE":
          G = {
            x: 0,
            y: 0 - I
          };
          break;
        case "TOPRIGHT":
        case "RIGHTTOP":
          G = {
            x: I,
            y: 0 - I
          };
          break;
        case "RIGHTMIDDLE":
          G = {
            x: I,
            y: 0
          };
          break;
        case "RIGHTBOTTOM":
        case "BOTTOMRIGHT":
          G = {
            x: I,
            y: I
          };
          break;
        case "BOTTOMMIDDLE":
          G = {
            x: 0,
            y: I
          };
          break;
        case "BOTTOMLEFT":
        case "LEFTBOTTOM":
          G = {
            x: 0 - I,
            y: I
          };
          break;
        case "LEFTMIDDLE":
          G = {
            x: 0 - I,
            y: 0
          };
          break
        }
        G.x += this.options.offset.x;
        G.y += this.options.offset.y;
        J = Object.extend({
          offset: G
        },
        {
          element: this.options.hook.tip,
          mouseHook: this.mouseHook,
          mouse: {
            top: C.pointerY || Event.pointerY(B) - K.top,
            left: C.pointerX || Event.pointerX(B) - K.left
          }
        });
        H = Tips.hook(this.wrapper, this.target, J);
        if (this.options.viewport) {
          var M = this.getPositionWithinViewport(H),
          L = M.stemInverse;
          H = M.position;
          H.left += L.vertical ? 2 * Prototip.toggleInt(G.x - this.options.offset.x) : 0;
          H.top += L.vertical ? 2 * Prototip.toggleInt(G.y - this.options.offset.y) : 0;
          if (this.stem && (this.stemInverse.horizontal != L.horizontal || this.stemInverse.vertical != L.vertical)) {
            this.positionStem(L)
          }
        }
        H = {
          left: H.left + "px",
          top: H.top + "px"
        };
        this.wrapper.setStyle(H)
      } else {
        J = Object.extend({
          offset: this.options.offset
        },
        {
          element: this.options.hook.tip,
          target: this.options.hook.target
        });
        H = Tips.hook(this.wrapper, this.target, Object.extend({
          position: true
        },
        J));
        H = {
          left: H.left + "px",
          top: H.top + "px"
        }
      }
      if (this.loader) {
        var E = Tips.hook(this.loader, this.target, Object.extend({
          position: true
        },
        J))
      }
      if (Tips.fixIE) {
        this.iframeShim.setStyle(H)
      }
    } else {
      var F = this.target.cumulativeOffset(),
      C = B.fakePointer || {},
      H = {
        left: ((this.options.fixed) ? F[0] : C.pointerX || Event.pointerX(B)) + this.options.offset.x,
        top: ((this.options.fixed) ? F[1] : C.pointerY || Event.pointerY(B)) + this.options.offset.y
      };
      if (!this.options.fixed && this.element !== this.target) {
        var D = this.element.cumulativeOffset();
        H.left += -1 * (D[0] - F[0]);
        H.top += -1 * (D[1] - F[1])
      }
      if (!this.options.fixed && this.options.viewport) {
        var M = this.getPositionWithinViewport(H),
        L = M.stemInverse;
        H = M.position;
        if (this.stem && (this.stemInverse.horizontal != L.horizontal || this.stemInverse.vertical != L.vertical)) {
          this.positionStem(L)
        }
      }
      H = {
        left: H.left + "px",
        top: H.top + "px"
      };
      this.wrapper.setStyle(H);
      if (this.loader) {
        this.loader.setStyle(H)
      }
      if (Tips.fixIE) {
        this.iframeShim.setStyle(H)
      }
    }
  },
  getPositionWithinViewport: function(C) {
    var E = {
      horizontal: false,
      vertical: false
    },
    D = this.wrapper.getDimensions(),
    B = document.viewport.getScrollOffsets(),
    A = document.viewport.getDimensions(),
    G = {
      left: "width",
      top: "height"
    };
    for (var F in G) {
      if ((C[F] + D[G[F]] - B[F]) > A[G[F]]) {
        C[F] = C[F] - (D[G[F]] + (2 * this.options.offset[F == "left" ? "x": "y"]));
        if (this.stem) {
          E[Tips._stemTranslation[G[F]]] = true
        }
      }
    }
    return {
      position: C,
      stemInverse: E
    }
  }
});
Object.extend(Prototip, {
  createCorner: function(G, H) {
    var F = arguments[2] || this.options,
    B = F.radius,
    E = F.border,
    D = new Element("canvas", {
      className: "cornerCanvas" + H.capitalize(),
      width: E + "px",
      height: E + "px"
    }),
    A = {
      top: (H.charAt(0) == "t"),
      left: (H.charAt(1) == "l")
    };
    if (D && D.getContext && D.getContext("2d")) {
      G.insert(D);
      var C = D.getContext("2d");
      C.fillStyle = F.backgroundColor;
      C.arc((A.left ? B: E - B), (A.top ? B: E - B), B, 0, Math.PI * 2, true);
      C.fill();
      C.fillRect((A.left ? B: 0), 0, E - B, E);
      C.fillRect(0, (A.top ? B: 0), E, E - B)
    } else {
      G.insert(new Element("div").setStyle({
        width: E + "px",
        height: E + "px",
        margin: 0,
        padding: 0,
        display: "block",
        position: "relative",
        overflow: "hidden"
      }).insert(new Element("v:roundrect", {
        fillcolor: F.backgroundColor,
        strokeWeight: "1px",
        strokeColor: F.backgroundColor,
        arcSize: (B / E * 0.5).toFixed(2)
      }).setStyle({
        width: 2 * E - 1 + "px",
        height: 2 * E - 1 + "px",
        position: "absolute",
        left: (A.left ? 0 : ( - 1 * E)) + "px",
        top: (A.top ? 0 : ( - 1 * E)) + "px"
      })))
    }
  }
});
Element.addMethods({
  setPngBackground: function(C, B) {
    C = $(C);
    var A = Object.extend({
      align: "top left",
      repeat: "no-repeat",
      sizingMethod: "scale",
      backgroundColor: ""
    },
    arguments[2] || {});
    C.setStyle(Tips.fixIE ? {
      filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + B + "'', sizingMethod='" + A.sizingMethod + "')"
    }: {
      background: A.backgroundColor + " url(" + B + ") " + A.align + " " + A.repeat
    });
    return C
  }
});
Prototip.Methods = {
  show: function() {
    Tips.raise(this);
    this.cancelHideAfter();
    var D = {};
    if (this.options.hook) {
      D.fakePointer = {
        pointerX: 0,
        pointerY: 0
      }
    } else {
      var A = this.target.cumulativeOffset(),
      C = this.target.cumulativeScrollOffset(),
      B = document.viewport.getScrollOffsets();
      A.left += ( - 1 * (C[0] - B[0]));
      A.top += ( - 1 * (C[1] - B[1]));
      D.fakePointer = {
        pointerX: A.left,
        pointerY: A.top
      }
    }
    if (this.options.ajax) {
      this.ajaxShow(D)
    } else {
      this.showDelayed(D)
    }
    this.hideAfter()
  }
};
Prototip.extend = function(A) {
  A.element.prototip = {};
  Object.extend(A.element.prototip, {
    show: Prototip.Methods.show.bind(A),
    hide: A.hide.bind(A),
    remove: Tips.remove.bind(Tips, A.element)
  })
};
Prototip.start();

