var initFunctions = new Array;

function doInitFunction(e) {
  if (arguments.callee.done) return;
  arguments.callee.done = true;
  // Real work starts here:
  l = initFunctions.length;
  for(var i=0; i<l; i++) {
    initFunctions[i](e);
  };
}

if (document.addEventListener) {
  // BEWARE! DOMContentLoaded is a Gecko-specific event!
  document.addEventListener("DOMContentLoaded", doInitFunction, false);
  document.addEventListener("load", doInitFunction, false);
} else if (document.attachEvent){
  document.attachEvent('load', doInitFunction);
}
window.onload = doInitFunction;



// =============== H e l p e r s ==============

ASCII_REPLACES = {
  'ą':'a', 'Ą':'A',
  'ć':'c', 'Ć':'C',
  'ę':'e', 'Ę':'E',
  'ł':'l', 'Ł':'L',
  'ń':'n', 'Ń':'N',
  'ó':'o', 'Ó':'O',
  'ś':'s', 'Ś':'S',
  'ź':'z', 'Ź':'Z',
  'ż':'z', 'Ż':'Z',
};

function asciize_char(ch) {
  return ASCII_REPLACES[ch] || ' ';
};

function asciize(text) {
  return (text || '').replace(/[^a-zA-Z0-9 ]/g,asciize_char).replace(/^\s+|\s+$/g,'').replace(/\s+/g,'_');
};


function cleanClass(name) {
  return (name || '').replace(/\s\s+/g,' ').replace(/^\s+|\s+$/g,'');
}

function addClass(elem, name) {
  if( new RegExp('\\b'+name+'\\b').test(elem.className) )
    return;
  elem.className = cleanClass( (elem.className || '') + ' ' + name );
}

function removeClass(elem, name) {
  var re = new RegExp('\\b'+name+'\\b');
  if( re.test(elem.className) ) {
    elem.className = cleanClass( elem.className.replace(re,'') );
  }
}

// Jeśli element miał klasę, usuwa ją i zwraca false,
// jeśli nie miał, dodaje i zwraca true.
// Innymi słowy, mówi czy klasę dodał.
//
// Mógłbym wykorzystać high level addClass, removeClass i hasClass,
// ale tak będzie efektywniej. To na tyle prosta funkcja, że nawet
// po takim 'rozwinięciu' jest czytelna.
function toggleClass(elem, name) {
  var re = new RegExp('\\b'+name+'\\b');
  if( re.test(elem.className) ) {
    // usuwamy
    elem.className = cleanClass( elem.className.replace(re,'') );
    return false;
  } else {
    // dodajemy
    elem.className = cleanClass( (elem.className || '') + ' ' + name );
    return true;
  }
}

function hasClass(elem, name) {
  return ( new RegExp('\\b'+name+'\\b').test(elem.className) );
}

function removeKids(node) {
  var el;
  while( el = node.firstChild )
    node.removeChild( el );
}


function cloneKids(srcNode, dstNode) {
  var el = srcNode.firstChild;
  while( el ) {
    // Wypadałoby sprawdzić, czy któryś z klonów nie ma atrybutu ID
    // bo po sklonowaniu będą w dokumencie dwa.
    dstNode.appendChild( el.cloneNode(true) );
    el = el.nextSibling;
  }
}

// Zwraca pierwszy element podanego typu spośród dzieci elementu elem.
// lub null.
function firstKidOfType(elem, name) {
  var kid = elem.firstChild;
  while(kid) {
    if( kid.tagName == name || kid.tagName == name.toUpperCase() )
      return kid;
    kid = kid.nextSibling;
  }
  return null;
}


function debuguj(msg) {
  if( typeof(console) == 'object' && console.debug ) {
    console.debug(msg);
  } else if( window.dump ) {
    window.dump(msg);
  }
}

