// $Id: jstools.js,v 1.1 2006/05/11 18:31:29 nedjo Exp $

/**
 * A set of helper functions, beyond the methods declared in drupal.js.
 */

function jsToolsHelpers() {};

/**
 * Return the path portion of an href.
 */
jsToolsHelpers.prototype.getPath = function(href) {
  return href.substring(jsTools.basePath.length + jsTools.query.length, href.length);
}

/**
 * Set a cookie.
 */
jsToolsHelpers.prototype.setCookie = function(sName, sValue, nDays) {
  var expires = "";
  if (nDays) {
    var d = new Date();
    d.setTime(d.getTime() + nDays * 24 * 60 * 60 * 1000);
    expires = '; expires=' + d.toGMTString();
  }

  document.cookie = sName + '=' + sValue + expires + '; path=/';
};

/**
 * Set a previously set cookie.
 */
jsToolsHelpers.prototype.getCookie = function(sName) {
  var re = new RegExp("(\;|^)[^;]*(" + sName + ")\=([^;]*)(;|$)");
  var res = re.exec(document.cookie);
  return res != null ? res[3] : null;
};

/**
 * Unset a cookie.
 */
jsToolsHelpers.prototype.removeCookie = function(name) {
  setCookie(name, '', -1);
};

/**
 * Attach an event to an element.
 */
jsToolsHelpers.prototype.addEvent = function(obj, type, fn) {
  if (!obj) {
    return;
  }
  if (obj.attachEvent) {
    obj['e'+type+fn] = fn;
    obj[type+fn] = function(){obj['e'+type+fn](window.event);}
    obj.attachEvent('on' + type, obj[type+fn]);
  }
  else if (obj.addEventListener) {			
    obj.addEventListener(type, fn, false);
  }
  else {
    var originalHandler = obj['on' + type];
    if (originalHandler) {
      obj['on' + type] = function(e){originalHandler(e);fn(e);}; 
    }
    else {
      obj['on' + type] = fn; 
    } 
  }
}

/**
 * Remove an event from an element.
 */
jsToolsHelpers.prototype.removeEvent = function(obj, type, fn) {
  if (obj.detachEvent) {
    if(obj[type+fn]) {
      obj.detachEvent( 'on'+type, obj[type+fn] );
      obj[type+fn] = null;
    }
  }
  else if (obj.removeEventListener) {
    obj.removeEventListener( type, fn, false );
  }
  else {
    obj["on" + type] = null;
  }
}

/**
 * Returns an event's source element.
 */
jsToolsHelpers.prototype.getSourceElement = function(e) {	
  if (!e) e = window.event;	
  var srcE = e.target ? e.target : e.srcElement
  if (!srcE) return null;
  if (srcE.nodeType == 3) srcE = srcE.parentNode; // safari weirdness		
  if (srcE.tagName.toUpperCase()=='LABEL' && e.type=='click') { 
    // When clicking a label, firefox fires the input onclick event
    // but the label remains the source of the event. In Opera and IE 
    // the source of the event is the input element. Which is the 
    // expected behavior, I suppose.		
    if (srcE.getAttribute('for')) {
      srcE = document.getElementById(srcE.getAttribute('for'));
    }
  }
  return srcE;
}

/**
 * If a target element has not bee set, return the document object.
 */
jsToolsHelpers.prototype.getTarget = function(elt) {
  return elt ? elt : document;
}

/**
 * A set of effects. These 'vanilla' effects can be overridden by effects libraries.
 */
var jsToolsEffects = function() {};

/**
 * Hide or display an element.
 */
jsToolsEffects.prototype.collapse = function(node) {
  toggleClass(node, 'collapsed');
}

/**
 * Scroll to a given element's vertical page position.
 */
jsToolsEffects.prototype.scrollTo = function(node) {
  var pos = absolutePosition(node);
  window.scrollTo(0, pos.y);
}

/**
 * The jsTools object registers and calls behaviours and holds their associated properties.
 */

if (jsToolsHelpers && jsToolsEffects) {
  var jsTools = {
    behaviors: {},
    helpers: new jsToolsHelpers(),
    effects: new jsToolsEffects(),
    init: function() {
      jsTools.attachBehaviors();
      // We detect core behaviours after inital attachment because they already register themselves
      // as load events.
      jsTools.detectCoreBehaviors();
    },
    attachBehaviors: function(behaviors, elt) {
      if (behaviors) {
        for(i = 0; behaviorName = behaviors[i]; i ++) {
          //jsTools.behaviors[behaviorName](elt);
        }
      }
      else {
        for(var behaviorName in jsTools.behaviors) {
          jsTools.behaviors[behaviorName](elt);
        }
      }
    },
    detectCoreBehaviors: function() {
      var coreBehaviors = ['upload', 'autocomplete'];
      for (var i = 0; behaviorName = coreBehaviors[i]; i++) {
        if (eval('window.' + behaviorName + 'AutoAttach')) {
          jsTools.behaviors[behaviorName] = eval(behaviorName + 'AutoAttach');
        }
      }
    },
    behaviourInvoke: function(behaviourName, elt) {
      if (jsTools.behaviors[behaviourName]) {
        jsTools.behaviors[behaviorName](elt);
      }
    }
  };
}


// Killswitch for all jstools behaviours.
// jsTools.init calls all registered behaviours' attach methods.
if (isJsEnabled()) {
  addLoadEvent(jsTools.init);
}

/**
 * All functions from here to end are temporary fixes to issues in drupal.js.
 */

/**
 * Parse a JSON response.
 *
 * The result is either the JSON object, or an object with 'status' 0 and 'data' an error message.
 */
function parseJson(data) {
  if ((data.substring(0, 1) != '{') && (data.substring(0, 1) != '[')) {
    return { status: 0, data: data.length ? data : 'Unspecified error' };
  }
  return eval('(' + data + ');');
}

/**
 * Removes a class name from an element
 */
function removeClass(node, className) {
  if (!hasClass(node, className)) {
    return false;
  }
  node.className = eregReplace('(^| )'+ className, '', node.className);
  node.className = eregReplace(className +'($| )', '', node.className);
  return true;
}

