/* ptt.js     v. 1.3.3

Modified by Klas Hatje, 2009-08-03:
    * Added support for SVG

Copyright (c) 2006 Marcel Hellkamp. All rights reserved.
Created 19.07.2006 by Marcel Hellkamp - Last modified: 22.09.2006

The latest version is available at http://dev.gsites.de/ptt

Features:
  * Flexible Text, HTML or AjAX-Tooltips with highly customisable CSS-Layouts
  * Impressive visual effects like fading, blending or growing tooltips
  * All done with (X)HTML "title" attribute. No onmouse*-attributes required.
  * Supported browsers: Firefox 1.5, Internet Explorer 5
    (Opera/Safari/... not tested. Feedback welcome)

Version history:
  * 1.0 Extended tooltips for all HTML-Tags that support onmouse*
  * 1.1 AjAX-Support (requires prototype library: http://prototype.conio.net/)
  * 1.2 Tooltip parameters (delay, stay, sticky, offsetX, offsetY)
  * 1.3 Support for visual effects like fading, blending or growing tooltips
        (requires scriptaculous library: http://script.aculo.us/)

Links:
  * http://dev.gsites.de (Developer homepage)
  * http://def.gsites.de/ptt (Project homepage and documentation)
  * http://prototype.conio.net/ (Prototype library)
  * http://script.aculo.us/ (Scriptaculous library)

License (short summary):
  You can use it, free of charge, for anything you like (which includes
  commercial applications); just do not remove the copyright remarks below.

LICENSE:
  This file is licensed under the terms of the MIT License.

  Copyright (c) 2006 Marcel Hellkamp. All rights reserved.

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  The above copyright notice, this permission notice and the following
  disclaimer shall be included in all copies or substantial portions of the
  Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.
*/

// This HTML-Tags will be recognized by ptt_init()
var ptt_tags = new Array('a','input','img','span');

// Only elements with one of these classes will be enabled for tooltip-support
// Leave empty to enable all elements regardless of its classes
var ptt_classes = new Array('ptt');

// This parameters will be default for all tooltips
var ptt_options = "effect:opacity;delay:200;offsetX:5;offsetY:15";

/****************************************************
 * Configuration done. Do not change the code below *
 ****************************************************/

// Prepare RegExps
var ptt_re_options = new RegExp('^(.*)\\((.*)\\)$', "i");
var ptt_re_parameter = new RegExp('^(.+):(.*)$', "i");

// Mouse Position
var ptt_pageX = 0;
var ptt_pageY = 0;

// ToolTip Stack
var ptt = new Array();

function ptt_init() {
  var x, skip = false, count=0;
  for(var i=0; i<ptt_tags.length; i++)
  {
    x = document.getElementsByTagName(ptt_tags[i]);
    for(var j=0; j<x.length; j++)
    {
      if( x[j].getAttribute("title") ) {

        // If x.className is of type SVGAnimatedString, the
        // baseVal of className contains the className as string
        if(String(x[j].className).match(/SVGAnimatedString/)) {
            classes = x[j].className.baseVal || "";
        } else {
            classes = x[j].className || "";
        }
        if(ptt_classes.length > 0) {
          classes = classes.split(" ");
          skip = false;
          for(var k=0; k<classes.length && !skip; k++) {
            for(var l=0; l<ptt_classes.length && !skip; l++) {
              if(classes[k] == ptt_classes[l]) {
                ptt_add(x[j]);
                skip = true;
                count = count + 1;
                if(count > 100) { // Let the browser rest some time
                  setTimeout('ptt_init()',200);
                  return;
                }
              }
            }
          }
        } else {
          ptt_add(x[j]);
          count = count + 1;
          if(count > 100) { // Let the browser rest some time
            setTimeout('ptt_init()',200);
            return;
          }
        }
      }
    }
  }
  // While document is loading, continuously try to find new elements
  if(count > 0) {
    setTimeout('ptt_init()',500);
  }
}

function ptt_add(x) {
  var title = x.getAttribute("title");
  var id = ptt.length;
  var tagId = "ptt" + id;
  var replace = false;
  var options = new Object();

  if(title.length < 3)
    return;

  //ptt_re_options
  var re_match = ptt_re_options.exec(title)
  if(re_match && re_match.length > 0) {
    title = re_match[1];
    options = ptth_options(re_match[2]);
  } else {
    options = ptth_options();
  }

  if(title.substring(0,1) == "!") {
    tagId = title.substring(1);
  } else if(title.substring(0,1) == "@") {
    ptt_create(tagId, 'loading ...');
    replace = title.substring(1);
  } else {
    ptt_create(tagId, title);
  }

  // Search and hide the ToolTip
  var tt = document.getElementById(tagId);
  if(!tt) return;
  tt.style.display = 'none';

  // Do some changes on the hover-tag
  x.setAttribute("title","");
  x.onmouseover = new Function("", "ptt_activate("+id+")");
  x.onmouseout = new Function("", "ptt_deactivate("+id+")");

  // If you have an onclick function, the currently shown
  // tooltip must be deactivated
  var onclickAttribute = x.getAttribute("onclick");
  x.setAttribute("onclick", "ptt_deactivate_all(); " + onclickAttribute);

  // If x.className is of type SVGAnimatedString, the
  // baseVal of className must be edited
  if(String(x.className).match(/SVGAnimatedString/)) {
    x.className.baseVal = x.className.baseVal + " ptt_tag";
  } else {
    x.className = x.className + " ptt_tag";
  }

  // Add tt to list
  var newptt = new Object();
  newptt["id"] = id;
  newptt["tagId"] = tagId;
  newptt["status"] = false;
  newptt["replace"] = replace;
  newptt["options"] = options;
  newptt["node"] = tt;

  // finally add ptt
  ptt.push(newptt);
  return;
}

function ptt_create(tagId, text) {
  var newdiv = document.createElement('span');
  newdiv.innerHTML = "<div id='"+tagId+"' class='ptt_tooltip'>"+text+"</div>";
  document.body.appendChild(newdiv);
}

function ptt_activate(id) {
  if(!ptt[id] || ptt[id]["status"]) return;
  ptt[id]["status"] = true;
  if(ptt[id]['options']['delay'] > 0)
    setTimeout('ptt_show('+id+');',ptt[id]['options']['delay']);
  else
    ptt_show(id);

  if(ptt[id]['replace'] && Ajax.Updater) {
    new Ajax.Updater(ptt[id]["tagId"],ptt[id]["replace"],{});
    ptt[id]["replace"] = false;
  }

  ptt_move(true);
}

function ptt_deactivate(id) {
  if(!ptt[id] || !ptt[id]["status"]) return;
  ptt[id]["status"] = false;

  if(ptt[id]['options']['stay'] > 0)
    setTimeout('ptt_hide("+id+")',ptt[id]['options']['stay']);
  else
    ptt_hide(id);
}

function ptt_show(id) {
  if(!ptt[id] || !ptt[id]["status"]) return;
  if(ptt[id]['options']['effect'] && Effect) {
    switch (ptt[id]['options']['effect']) {
      case "blind":
        new Effect.BlindDown(ptt[id]["node"],{duration:0.5}); return;
      case "opacity":
        new Effect.Appear(ptt[id]["node"],{duration:0.5}); return;
      case "size":
        new Effect.Grow(ptt[id]["node"],{duration:0.5}); return;
      case "slide":
        new Effect.SlideDown(ptt[id]["node"],{duration:0.5}); return;
    }
  }
  // No (or unknown) Effect
  ptt[id]["node"].style.display = "block";
}

function ptt_hide(id) {
  if(!ptt[id] || ptt[id]["status"]) return;

  if(ptt[id]['options']['effect'] && Effect) {
    switch (ptt[id]['options']['effect']) {
      case "blind":
        new Effect.BlindUp(ptt[id]["node"],{duration:0.25}); return;
      case "opacity":
        new Effect.Fade(ptt[id]["node"],{duration:0.25}); return;
      case "size":
        new Effect.Shrink(ptt[id]["node"],{duration:0.25}); return;
      case "slide":
        new Effect.SlideUp(ptt[id]["node"],{duration:0.25}); return;
    }
  }
  // No (or unknown) Effect
  ptt[id]["node"].style.display = "none";
}

function ptt_move(evenStatics) {
  for(var i=0; i < ptt.length; i++) {
    if(ptt[i]["status"] && (evenStatics || !ptt[i]['options']['static'])) {
      ptt[i]["node"].style.left
        = (ptt_pageX*1 + ptt[i]['options']['offsetX']*1) + "px";
      ptt[i]["node"].style.top
        = (ptt_pageY*1 + ptt[i]['options']['offsetY']*1) + "px";
    }
  }
}

function ptth_options(str) {
  var res = new Array();
  var opt = new Object();
      opt['delay']  = 0;
      opt['stay']   = 0;
      opt['static'] = false;
      opt['offsetX'] = 0;
      opt['offsetY'] = 0;
      opt['effect'] = false;

  str = ptt_options + ';' + str;
  str = str.split(/;/);
  for(var i=0; i<str.length; i++) {
    res = ptt_re_parameter.exec(str[i])
    if(res) {
      if(res[2] == 'false' || res[2] == 'no' || res[2] == 'off' || !res[2])
        res[2] = false;
      if(res[2] == 'true' || res[2] == 'yes' || res[2] == 'on')
        res[2] = true;
      opt[res[1]] = res[2];
    }
  }
  return opt;
}

function ptt_deactivate_all() {
       for(var i=0; i<ptt.length; i++)
        {
            ptt_deactivate(i);
        }
}

var ptt_onMouseMoveBackup = document.onmousemove;
document.onmousemove = function(e) {
  e = e || window.event;

  if(e.pageX) { // Mozilla
    ptt_pageX = e.pageX;
    ptt_pageY = e.pageY;
  } else { // IEx
    ptt_pageX = e.clientX + (document.documentElement? document.documentElement.scrollLeft: document.body.scrollLeft);
    ptt_pageY = e.clientY + (document.documentElement? document.documentElement.scrollTop: document.body.scrollTop);
  }
  ptt_move();

  if(ptt_onMouseMoveBackup)
    ptt_onMouseMoveBackup(e);
}

var ptt_onLoadBackup = window.onload;
window.onload=function(e) {
  if(ptt_onLoadBackup)
    ptt_onLoadBackup(e);

 ptt_deactivate_all();
  ptt_init();
}
ptt_init();

if(Ajax && Ajax.Responders && Ajax.Responders.register) {
  Ajax.Responders.register({onComplete: function() {ptt_init()}});
}

