// $Id: drupal.js,v 1.22.2.4 2006/12/01 14:57:29 killes Exp $

/**
 * Only enable Javascript functionality if all required features are supported.
 */
function isJsEnabled() {
  if (typeof document.jsEnabled == 'undefined') {
    // Note: ! casts to boolean implicitly.
    document.jsEnabled = !(
     !document.getElementsByTagName ||
     !document.createElement        ||
     !document.createTextNode       ||
     !document.documentElement      ||
     !document.getElementById);
  }
  return document.jsEnabled;
}

// Global Killswitch on the <html> element
if (isJsEnabled()) {
  document.documentElement.className = 'js';
}

/**
 * Make IE's XMLHTTP object accessible through XMLHttpRequest()
 */
if (typeof XMLHttpRequest == 'undefined') {
  XMLHttpRequest = function () {
    var msxmls = ['MSXML3', 'MSXML2', 'Microsoft']
    for (var i=0; i < msxmls.length; i++) {
      try {
        return new ActiveXObject(msxmls[i]+'.XMLHTTP')
      }
      catch (e) { }
    }
    throw new Error("No XML component installed!");
  }
}

/**
 * Creates an HTTP GET request and sends the response to the callback function.
 *
 * Note that dynamic arguments in the URI should be escaped with encodeURIComponent().
 */
function HTTPGet(uri, callbackFunction, callbackParameter) {
  var xmlHttp = new XMLHttpRequest();
  var bAsync = true;
  if (!callbackFunction) {
    bAsync = false;
  }

  xmlHttp.open('GET', uri, bAsync);
  xmlHttp.send(null);

  if (bAsync) {
    xmlHttp.onreadystatechange = function() {
      if (xmlHttp.readyState == 4) {
        callbackFunction(xmlHttp.responseText, xmlHttp, callbackParameter);
      }
    }
    return xmlHttp;
  }
  else {
    return xmlHttp.responseText;
  }
}

/**
 * Creates an HTTP POST request and sends the response to the callback function
 *
 * Note: passing null or undefined for 'object' makes the request fail in Opera 8.
 *       Pass an empty string instead.
 */
function HTTPPost(uri, callbackFunction, callbackParameter, object) {
  var xmlHttp = new XMLHttpRequest();
  var bAsync = true;
  if (!callbackFunction) {
    bAsync = false;
  }
  xmlHttp.open('POST', uri, bAsync);

  var toSend = '';
  if (typeof object == 'object') {
    xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    for (var i in object) {
      toSend += (toSend ? '&' : '') + i + '=' + encodeURIComponent(object[i]);
    }
  }
  else {
    toSend = object;
  }
  xmlHttp.send(toSend);

  if (bAsync) {
    xmlHttp.onreadystatechange = function() {
      if (xmlHttp.readyState == 4) {
        callbackFunction(xmlHttp.responseText, xmlHttp, callbackParameter);
      }
    }
    return xmlHttp;
  }
  else {
    return xmlHttp.responseText;
  }
}

/**
 * Redirects a button's form submission to a hidden iframe and displays the result
 * in a given wrapper. The iframe should contain a call to
 * window.parent.iframeHandler() after submission.
 */
function redirectFormButton(uri, button, handler) {
  // (Re)create an iframe to target.
  createIframe();

  // Trap the button
  button.onmouseover = button.onfocus = function() {
    button.onclick = function() {
      // Prepare variables for use in anonymous function.
      var button = this;
      var action = button.form.action;
      var target = button.form.target;

      // Redirect form submission
      this.form.action = uri;
      this.form.target = 'redirect-target';

      handler.onsubmit();

      // Set iframe handler for later
      window.iframeHandler = function () {
        var iframe = $('redirect-target');
        // Restore form submission
        button.form.action = action;
        button.form.target = target;

        // Get response from iframe body
        try {
          response = (iframe.contentWindow || iframe.contentDocument || iframe).document.body.innerHTML;
          // Firefox 1.0.x hack: Remove (corrupted) control characters
          response = response.replace(/[\f\n\r\t]/g, ' ');
          if (window.opera) {
            // Opera-hack: it returns innerHTML sanitized.
            response = response.replace(/&quot;/g, '"');
          }
        }
        catch (e) {
          response = null;
        }

        jQuery('redirect-target').onload = null;
        jQuery('redirect-target').src = 'about:blank';

        response = parseJson(response);
        // Check response code
        if (response.status == 0) {
          handler.onerror(response.data);
          return;
        }
        handler.oncomplete(response.data);
      }

      return true;
    }
  }
  button.onmouseout = button.onblur = function() {
    button.onclick = null;
  }
}

/**
 * Adds a function to the window onload event
 */
function addLoadEvent(func) {
  var oldOnload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  }
  else {
    window.onload = function() {
      oldOnload();
      func();
    }
  }
}

/**
 * Adds a function to a given form's submit event
 */
function addSubmitEvent(form, func) {
  var oldSubmit = form.onsubmit;
  if (typeof oldSubmit != 'function') {
    form.onsubmit = func;
  }
  else {
    form.onsubmit = function() {
      return oldSubmit() && func();
    }
  }
}

/**
 * Retrieves the absolute position of an element on the screen
 */
function absolutePosition(el) {
  var sLeft = 0, sTop = 0;
  var isDiv = /^div$/i.test(el.tagName);
  if (isDiv && el.scrollLeft) {
    sLeft = el.scrollLeft;
  }
  if (isDiv && el.scrollTop) {
    sTop = el.scrollTop;
  }
  var r = { x: el.offsetLeft - sLeft, y: el.offsetTop - sTop };
  if (el.offsetParent) {
    var tmp = absolutePosition(el.offsetParent);
    r.x += tmp.x;
    r.y += tmp.y;
  }
  return r;
};

function dimensions(el) {
  return { width: el.offsetWidth, height: el.offsetHeight };
}

/**
 * Returns true if an element has a specified class name
 */
function hasClass(node, className) {
  if (node.className == className) {
    return true;
  }
  var reg = new RegExp('(^| )'+ className +'($| )')
  if (reg.test(node.className)) {
    return true;
  }
  return false;
}

/**
 * Adds a class name to an element
 */
function addClass(node, className) {
  if (hasClass(node, className)) {
    return false;
  }
  node.className += ' '+ className;
  return true;
}

/**
 * Removes a class name from an element
 */
function removeClass(node, className) {
  if (!hasClass(node, className)) {
    return false;
  }
  // Replaces words surrounded with whitespace or at a string border with a space. Prevents multiple class names from being glued together.
  node.className = eregReplace('(^|\\s+)'+ className +'($|\\s+)', ' ', node.className);
  return true;
}

/**
 * Toggles a class name on or off for an element
 */
function toggleClass(node, className) {
  if (!removeClass(node, className) && !addClass(node, className)) {
    return false;
  }
  return true;
}

/**
 * Emulate PHP's ereg_replace function in javascript
 */
function eregReplace(search, replace, subject) {
  return subject.replace(new RegExp(search,'g'), replace);
}

/**
 * Removes an element from the page
 */
function removeNode(node) {
  if (typeof node == 'string') {
    node = $(node);
  }
  if (node && node.parentNode) {
    return node.parentNode.removeChild(node);
  }
  else {
    return false;
  }
}

/**
 * Prevents an event from propagating.
 */
function stopEvent(event) {
  if (event.preventDefault) {
    event.preventDefault();
    event.stopPropagation();
  }
  else {
    event.returnValue = false;
    event.cancelBubble = true;
  }
}

/**
 * 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) != '{') {
    return { status: 0, data: data.length ? data : 'Unspecified error' };
  }
  return eval('(' + data + ');');
}

/**
 * Create an invisible iframe for form submissions.
 */
function createIframe() {
  // Delete any previous iframe
  deleteIframe();
  // Note: some browsers require the literal name/id attributes on the tag,
  // some want them set through JS. We do both.
  window.iframeHandler = function () {};
  var div = document.createElement('div');
  div.id = 'redirect-holder';
  div.innerHTML = '<iframe name="redirect-target" id="redirect-target" class="redirect" onload="window.iframeHandler();"></iframe>';
  var iframe = div.firstChild;
  with (iframe) {
    name = 'redirect-target';
    setAttribute('name', 'redirect-target');
    id = 'redirect-target';
  }
  with (iframe.style) {
    position = 'absolute';
    height = '1px';
    width = '1px';
    visibility = 'hidden';
  }
  document.body.appendChild(div);
}

/**
 * Delete the invisible iframe for form submissions.
 */
function deleteIframe() {
  var holder = $('redirect-holder');
  if (holder != null) {
    removeNode(holder);
  }
}

/**
 * Wrapper around document.getElementById().
//function $(id) {
//  return document.getElementById(id);
//}
*/

/* /////////////////////////////////////////////////////////////////////// collapse.js ///////////////////////////////////////////////////////////////////*/

if (isJsEnabled()) {
  addLoadEvent(collapseAutoAttach);
}

function collapseAutoAttach() {
  var fieldsets = document.getElementsByTagName('fieldset');
  var legend, fieldset;
  for (var i = 0; fieldset = fieldsets[i]; i++) {
    if (!hasClass(fieldset, 'collapsible')) {
      continue;
    }
    legend = fieldset.getElementsByTagName('legend');
    if (legend.length == 0) {
      continue;
    }
    legend = legend[0];
    var a = document.createElement('a');
    a.href = '#';
    a.onclick = function() {
      toggleClass(this.parentNode.parentNode, 'collapsed');
      if (!hasClass(this.parentNode.parentNode, 'collapsed')) {
        collapseScrollIntoView(this.parentNode.parentNode);
        if (typeof textAreaAutoAttach != 'undefined') {
          // Add the grippie to a textarea in a collapsed fieldset.
          textAreaAutoAttach(null, this.parentNode.parentNode);
        }
      }
      this.blur();
      return false;
    };
    a.innerHTML = legend.innerHTML;
    while (legend.hasChildNodes()) {
      removeNode(legend.childNodes[0]);
    }
    legend.appendChild(a);
    collapseEnsureErrorsVisible(fieldset);
  }
}

function collapseEnsureErrorsVisible(fieldset) {
  if (!hasClass(fieldset, 'collapsed')) {
    return;
  }
  var inputs = [];
  inputs = inputs.concat(fieldset.getElementsByTagName('input'));
  inputs = inputs.concat(fieldset.getElementsByTagName('textarea'));
  inputs = inputs.concat(fieldset.getElementsByTagName('select'));
  for (var j = 0; j<3; j++) {
    for (var i = 0; i < inputs[j].length; i++) {
      if (hasClass(inputs[j][i], 'error')) {
        return removeClass(fieldset, 'collapsed');
      }
    }
  }
}

function collapseScrollIntoView(node) {
  var h = self.innerHeight || document.documentElement.clientHeight || document.body.clientHeight || 0;
  var offset = self.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
  var pos = absolutePosition(node);
  if (pos.y + node.scrollHeight > h + offset) {
    if (node.scrollHeight > h) {
      window.scrollTo(0, pos.y);
    } else {
      window.scrollTo(0, pos.y + node.scrollHeight - h);
    }
  }
}

/* /////////////////////////////////////////////////////////////////////// autocomplete.js ///////////////////////////////////////////////////////////////////*/
// $Id: autocomplete.js,v 1.11.2.2 2006/12/01 14:51:36 killes Exp $

// Global Killswitch
if (isJsEnabled()) {
  addLoadEvent(autocompleteAutoAttach);
}

/**
 * Attaches the autocomplete behaviour to all required fields
 */
function autocompleteAutoAttach() {
  var acdb = [];
  var inputs = document.getElementsByTagName('input');
  for (i = 0; input = inputs[i]; i++) {
    if (input && hasClass(input, 'autocomplete')) {
      uri = input.value;
      if (!acdb[uri]) {
        acdb[uri] = new ACDB(uri);
      }
      input = $(input.id.substr(0, input.id.length - 13));
      input.setAttribute('autocomplete', 'OFF');
      addSubmitEvent(input.form, autocompleteSubmit);
      new jsAC(input, acdb[uri]);
    }
  }
}

/**
 * Prevents the form from submitting if the suggestions popup is open
 */
function autocompleteSubmit() {
  var popup = document.getElementById('autocomplete');
  if (popup) {
    popup.owner.hidePopup();
    return false;
  }
  return true;
}


/**
 * An AutoComplete object
 */
function jsAC(input, db) {
  var ac = this;
  this.input = input;
  this.db = db;
  this.input.onkeydown = function (event) { return ac.onkeydown(this, event); };
  this.input.onkeyup = function (event) { ac.onkeyup(this, event) };
  this.input.onblur = function () { ac.hidePopup(); ac.db.cancel(); };
  this.popup = document.createElement('div');
  this.popup.id = 'autocomplete';
  this.popup.owner = this;
};

/**
 * Hides the autocomplete suggestions
 */
jsAC.prototype.hidePopup = function (keycode) {
  if (this.selected && ((keycode && keycode != 46 && keycode != 8 && keycode != 27) || !keycode)) {
    this.input.value = this.selected.autocompleteValue;
  }
  if (this.popup.parentNode && this.popup.parentNode.tagName) {
    removeNode(this.popup);
  }
  this.selected = false;
}


/**
 * Handler for the "keydown" event
 */
jsAC.prototype.onkeydown = function (input, e) {
  if (!e) {
    e = window.event;
  }
  switch (e.keyCode) {
    case 40: // down arrow
      this.selectDown();
      return false;
    case 38: // up arrow
      this.selectUp();
      return false;
    default: // all other keys
      return true;
  }
}

/**
 * Handler for the "keyup" event
 */
jsAC.prototype.onkeyup = function (input, e) {
  if (!e) {
    e = window.event;
  }
  switch (e.keyCode) {
    case 16: // shift
    case 17: // ctrl
    case 18: // alt
    case 20: // caps lock
    case 33: // page up
    case 34: // page down
    case 35: // end
    case 36: // home
    case 37: // left arrow
    case 38: // up arrow
    case 39: // right arrow
    case 40: // down arrow
      return true;

    case 9:  // tab
    case 13: // enter
    case 27: // esc
      this.hidePopup(e.keyCode);
      return true;

    default: // all other keys
      if (input.value.length > 0)
        this.populatePopup();
      else
        this.hidePopup(e.keyCode);
      return true;
  }
}

/**
 * Puts the currently highlighted suggestion into the autocomplete field
 */
jsAC.prototype.select = function (node) {
  this.input.value = node.autocompleteValue;
}

/**
 * Highlights the next suggestion
 */
jsAC.prototype.selectDown = function () {
  if (this.selected && this.selected.nextSibling) {
    this.highlight(this.selected.nextSibling);
  }
  else {
    var lis = this.popup.getElementsByTagName('li');
    if (lis.length > 0) {
      this.highlight(lis[0]);
    }
  }
}

/**
 * Highlights the previous suggestion
 */
jsAC.prototype.selectUp = function () {
  if (this.selected && this.selected.previousSibling) {
    this.highlight(this.selected.previousSibling);
  }
}

/**
 * Highlights a suggestion
 */
jsAC.prototype.highlight = function (node) {
  removeClass(this.selected, 'selected');
  addClass(node, 'selected');
  this.selected = node;
}

/**
 * Unhighlights a suggestion
 */
jsAC.prototype.unhighlight = function (node) {
  removeClass(node, 'selected');
  this.selected = false;
}

/**
 * Positions the suggestions popup and starts a search
 */
jsAC.prototype.populatePopup = function () {
  var ac = this;
  var pos = absolutePosition(this.input);
  this.selected = false;
  this.popup.style.top   = (pos.y + this.input.offsetHeight) +'px';
  this.popup.style.left  = pos.x +'px';
  this.popup.style.width = (this.input.offsetWidth - 4) +'px';
  this.db.owner = this;
  this.db.search(this.input.value);
}

/**
 * Fills the suggestion popup with any matches received
 */
jsAC.prototype.found = function (matches) {
  while (this.popup.hasChildNodes()) {
    this.popup.removeChild(this.popup.childNodes[0]);
  }
  if (!this.popup.parentNode || !this.popup.parentNode.tagName) {
    document.getElementsByTagName('body')[0].appendChild(this.popup);
  }
  var ul = document.createElement('ul');
  var ac = this;

  for (key in matches) {
    var li = document.createElement('li');
    var div = document.createElement('div');
    div.innerHTML = matches[key];
    li.appendChild(div);
    li.autocompleteValue = key;
    li.onmousedown = function() { ac.select(this); };
    li.onmouseover = function() { ac.highlight(this); };
    li.onmouseout  = function() { ac.unhighlight(this); };
    ul.appendChild(li);
  }

  if (ul.childNodes.length > 0) {
    this.popup.appendChild(ul);
  }
  else {
    this.hidePopup();
  }
  removeClass(this.input, 'throbbing');
}

/**
 * An AutoComplete DataBase object
 */
function ACDB(uri) {
  this.uri = uri;
  this.delay = 300;
  this.cache = {};
}

/**
 * Performs a cached and delayed search
 */
ACDB.prototype.search = function(searchString) {
  this.searchString = searchString;
  if (this.cache[searchString]) {
    return this.owner.found(this.cache[searchString]);
  }
  if (this.timer) {
    clearTimeout(this.timer);
  }
  var db = this;
  this.timer = setTimeout(function() {
    addClass(db.owner.input, 'throbbing');
    db.transport = HTTPGet(db.uri +'/'+ encodeURIComponent(searchString), db.receive, db);
  }, this.delay);
}

/**
 * HTTP callback function. Passes suggestions to the autocomplete object
 */
ACDB.prototype.receive = function(string, xmlhttp, acdb) {
  // Note: Safari returns 'undefined' status if the request returns no data.
  if (xmlhttp.status != 200 && typeof xmlhttp.status != 'undefined') {
    removeClass(acdb.owner.input, 'throbbing');
    return alert('An HTTP error '+ xmlhttp.status +' occured.\n'+ acdb.uri);
  }
  // Parse back result
  var matches = parseJson(string);
  if (typeof matches['status'] == 'undefined' || matches['status'] != 0) {
    acdb.cache[acdb.searchString] = matches;
    acdb.owner.found(matches);
  }
}

/**
 * Cancels the current autocomplete request
 */
ACDB.prototype.cancel = function() {
  if (this.owner) removeClass(this.owner.input, 'throbbing');
  if (this.timer) clearTimeout(this.timer);
  if (this.transport) {
    this.transport.onreadystatechange = function() {};
    this.transport.abort();
  }
}

var vote_in_progress = false;
function pollvote(id){
    if(!vote_in_progress){
	vote_in_progress = true;
	HTTPGet('/pollvote/'+id, function(data){
		if(data){
		    document.getElementById('votes-'+id).innerHTML = data;
		    var i=0;
		    while(document.getElementById('votelink-'+i)){
			document.getElementById('votelink-'+i).style.display = 'none';
			i++;
		    }
		}
	    });
    }
    return false;
}

function approveAjaxAutoAttach(){
	var nsdb = [];
	var spans = document.getElementsByTagName('span');
	for (var i = 0; span = spans[i]; i++) {
		if (span && hasClass(span, 'ns_switch')) {
			uri = span.getAttribute('title');
			span.removeAttribute('title');
			span.setAttribute('title', 'Odobri prikazivanje ovog sadrzaja');
			if (!nsdb[uri])
				nsdb[uri] = new NSDB(span, uri);
		}
	}
}
function NSDB(elt, uri) {
    var db = this;
	// By making the span element a property of this object,
	// we get the ability to attach behaviours to that element.
	this.elt= elt;
	this.uri = uri;
	this.elt.onclick = function() {
		HTTPGet(db.uri, db.receive, db);
		db.elt.innerHTML="done";
		db.elt.onclick=null;
		db.elt.style.cursor="default";
	}
}
