var Base = new Class({
  isIE: false,
  running: false,
  loaded: false,
  usingComponents: ["Menu","Collapse","Page_admin","Calendar","Tab","Popup","Loader","Flickr"],
  components: false,
  runningComponents: false,
  componentsElements: false,
  arguments: false,
  urlCallbacks: false,
  currentUrl: false,
  functions: false,
  
  initialize: function() 
  {
    this.components = new Array();
    this.runningComponents = new Array();
    this.componentsElements = new Array();
    this.urlCallbacks = new Array();
    this.functions = new Array();

    this.initializeQuery();
    if (navigator.userAgent.indexOf("MSIE") >= 0) this.isIE = true;
  },
  
  init: function() 
  {
    this.initializeComponents();
    this.initializeCallbacks();
    this.loaded = true;
  },

  loadComponents: function()
  {
    for (var i = 0; i < this.usingComponents.length; i++) {
      var name = this.usingComponents[i];
      var elements = $$(".jsComponent"+name);
      if (elements != "") {
        this.loadJS("/lib/js/components/"+name.toLowerCase()+"/"+name+".class.js");
        elements.each(function(element) {
          if (element.hasClass("preload")) element.remove();
        });
        this.componentsElements[i] = elements;
      } else this.usingComponents[i] = "";
    }
    this.loadJS("/lib/js/base/bootstrap.js");
    this.running = true;
  },

  parseElement: function (element)
  {
    var update = false;
    for (var i = 0; i < this.usingComponents.length; i++) {
      var name = this.usingComponents[i];
      if (name == "") continue;

      var elements = $ES(".jsComponent"+name, element);
      if (elements != "") {
        for (var j = 0; j < elements.length; j++) {
          this.componentsElements[i].push(elements[j]);
          update = true;
        }
      } 
    }
    if (update) this.initializeComponents();
  },

  initializeQuery: function ()
  {
    this.arguments = window.location.href.split("#");
    if (this.arguments.length > 1) {
      this.arguments = this.arguments[1].split("|");
    }
  },
  
  initializeComponents: function()
  {
    for (var i = 0; i < this.usingComponents.length; i++) {
      var name = this.usingComponents[i];
      if (name == "") continue;
      var elements = this.componentsElements[i];

      if (elements != "") {
        for (var j = 0; j < elements.length; j++) {
          var componentId = (i+1)*j;
          if (typeof(this.runningComponents[name]) != "object") 
            this.runningComponents[name] = new Array();
          if (typeof(this.components[elements[j].id]) != "object") {
            this.components[elements[j].id] = eval("new "+name+"('"+elements[j].id+"')");
          }
          if ($(elements[j]).hasClass("jsComponent"+name)) {
            this.components[elements[j].id].run(elements[j]);
          }
          this.runningComponents[name][elements[j].id] = this.components[elements[j].id]
          $(elements[j]).removeClass("jsComponent"+name);
        }
      }
    }
  },
  
  initializeCallbacks: function()
  {
    window.addEvent('resize', function() { base.repaint(); });
    setInterval(this.urlCallback.bind(this), 250);
  },

  newComponent: function( obj )
  {
    if (!obj.type || !obj.id) return false;

    var component = new Element("div",{
      "id": obj.id,
      "class": "jsComponent"+obj.type
    });
    if (obj.options) {
      for (var i in obj.options) {
        var input = new Element("input", {
          "type": "hidden",
          "class": "jsParam",
          "name": i,
          "value": obj.options[i]
        });
        component.appendChild(input);
      }
    }
    var header = new Element("div", { "class": "header" });
    var content = new Element("div", { "class": "content" });
    component.appendChild(header); component.appendChild(content);
    return component;
  },

  addFunction: function ( func )
  {
    this.functions.push(func);
  },

  addComponent: function ( componentId ) {
    var component = $(componentId);
    if (!component) return false;
    if (component.className.search(/jsComponent/) < 0) return false;
    var type = component.className.replace("jsComponent","");
    
    this.components[component.id] = eval("new "+type+"('"+component.id+"')");
    this.components[component.id].run(component);
    component.className = "";
  },

  repaint: function()
  {
    this.components.each ( function ( id ) {
      if (this.components[id]) this.components[id].repaint();
    });
  },

  loadJS: function( jsFile )
  {
    var rnd = Math.random();
    var script = new Element("script", {
      "type": "text/javascript",
      "src": jsFile+"?"+rnd
    });

    document.getElement("head").appendChild(script);
  },

  urlCallback: function ( ) 
  {
    if (this.currentUrl == document.location.href) return true;
    var urlParts = document.location.href.split("#");
    if (urlParts.length <= 1) return true;
    urlParts.shift();
    var url = "";
    if (urlParts != "") url = urlParts.join("#");
    this.urlCallbacks.each( function (c) { c(url); } );
    this.currentUrl = document.location.href; 
  },

  registerURLCallback: function ( callback )
  {
    this.urlCallbacks.push(callback);
  },
  
  getWindowSize: function ()
  {
    return {
      "width": (window.getWidth()<=0?document.body.clientWidth:window.getWidth()),
      "height": (window.getHeight()<=0?document.body.clientHeight:window.getHeight())
    }
  }
});

/* Initialize Javascript framework */
var base;

var callback = function() { if (!base) { base = new Base(); } else if (!base.running) { base.loadComponents(); } }
window.addEvent('domready', callback);
window.addEvent('load', callback);
