Function.prototype.method = function (name, func) {
    this.prototype[name] = func;
    return this;
}

Function.method('inherits', function (parent) {
    var sc = parent;
    var d = 0, p = (this.prototype = new parent());

    this.method('callMethod', function importMethod(sc, name) {
      return sc.prototype[name].apply(this, Array.prototype.slice.apply(arguments, [2]));
    });

    this.method('superclass', function superclass(name) {
        var f, r, t = d, v = parent.prototype;
        if (t) {
            while (t) {
                v = v.constructor.prototype;
                t -= 1;
            }
            f = v[name];
        } else {
            f = p[name];
            if (f == this[name]) {
                f = v[name];
            }
        }
        d += 1;
        r = f.apply(this, Array.prototype.slice.apply(arguments, [1]));
        d -= 1;
        return r;
    });
    return this;
})


Function.method('swiss', function (parent) {
    for (var i = 1; i < arguments.length; i += 1) {
        var name = arguments[i];
        this.prototype[name] = parent.prototype[name];
    }
    return this;
})

function HTMLAction(func, owner, params) {
  this.func   = func;
  this.owner  = owner;
  this.params = params;
  this.isHTMLAction = true;
  if (!this.params) this.params = new Array();
}

HTMLAction.prototype.getFunction = function() { return this.func; }
HTMLAction.prototype.getOwner = function() { return this.owner; }
HTMLAction.prototype.getParams = function() { return this.params; }

HTMLAction.prototype.callAction = function() {
  this.func.apply(this.owner, Array.prototype.slice.apply(arguments, [1]));
}

HTMLAction.prototype.call = function() {
  var args = arrayConcat(arguments, this.params);
  return this.func.apply(this.owner, args);
}

HTMLAction.prototype.apply = function(o, p) {
  var args = arrayConcat(arrayConcat([o], p), this.params);
  return this.func.apply(this.owner, args);
}

HTMLAction.prototype.toString = function() {
  return '[HTMLAction]';
}

HTMLObject.prototype.getMaker = function() {
  return this.maker ? this.maker : this.maker = new HTMLMakerInfo(this);
}

function HTMLObject(sys, formID, code) {
  this.sys    = sys;
  this.formID = formID;
  this.code   = code;
}

HTMLObject.prototype.getSystem = function() { return this.sys; }
HTMLObject.prototype.getForm = function() { return this.formID; }
HTMLObject.prototype.getCode   = function() { return this.code; }

HTMLObject.prototype.attachEvent = function(obj, type, fn, owner, params) {
  if (type.length > 2 && type.substring(0, 2) == 'on')
    type = type.substring(2, type.length);

  if (fn.isHTMLAction) {
    owner = fn.getOwner();
    if (fn.getParams().length > 0)
      params = fn.getParams();
    fn = fn.getFunction();
  }
  obj['event_on'+type] = fn;
  if (owner && owner.isRule) {
    obj['on'+type] = associateRuleWithEvent(obj, 'event_on'+type, owner?owner:this);
  } else {
    obj['on'+type] = associateObjWithEvent(obj, 'event_on'+type, owner?owner:this, params);
  }
  EventCache.add(obj, type, fn);
}

HTMLObject.prototype.removeEvent = function(obj, type) {
  obj['event_'+type] = null;
  obj['on'+type] = null;
}

HTMLObject.prototype.toString = function() {
  return '[HTMLObject]';
}

HTMLObject.prototype.checkPost = function() {
  return true;
}

HTMLObject.prototype.timeout = function(handler, delay, fparams){
  var self = this;
  var params = fparams;
  var wrapper = function(){if(params) handler.apply(self, params); else handler.apply(self);};
  return window.setTimeout(wrapper, delay ? delay : 0);
}

HTMLObject.prototype.getAction = function(fun, params){
  var f = typeof(fun)=="string"?this[fun]:fun;
  return new HTMLAction(f, this, params);
}

HTMLObject.prototype.getActionFunction = function(fun, params){
  var context = params;
  var owner = this;
  return function(e) {
    var paramscopy = new Array();
    paramscopy.push(e);
    if (params) paramscopy = paramscopy.concat(params);
    return fun.apply(owner, paramscopy);
  }
}

HTMLObject.prototype.flush = function() {
  this.doc = null;
  this.div = null;
}

HTMLObject.prototype.free = function() {
  if (this.doc && this.div)
    this.doc.removeChild(this.div);
  return this;
}

HTMLObject.prototype.loadScripts = function() {
 //Deve ser sobrecarregado
}


//Funções Úteis

function getKey(evt) {
  if (!evt) evt = event;
  return evt.keyCode;
}

function checkKey(evt, o, keys) {
  if (!evt) evt = event;
  var altKey   = false;
  var ctrlKey  = false;
  var shiftKey = false;
  var target   = evt.target || evt.srcElement;
  var r = true;

  if (w3c) {
    if (document.layers) {
      altKey = ((evt.modifiers & Event.ALT_MASK) > 0);
      ctrlKey = ((evt.modifiers & Event.CONTROL_MASK) > 0);
      shiftKey = ((evt.modifiers & Event.SHIFT_MASK) > 0);
    } else {
      altKey = evt.altKey;
      ctrlKey = evt.ctrlKey;
      shiftKey = evt.shiftKey;
    }
  } else {
    altKey = evt.altKey;
    ctrlKey = evt.ctrlKey;
    shiftKey = evt.shiftKey;
  }

  if (!altKey && !ctrlKey && o.enabled && !o.readonly && o.visible && evt.keyCode == 116) {
    if (o.onF5press) o.onF5press.call(o, evt);
    r = false;
  }

  if (!keys) keys = [13, 10, 9];

  if (!ctrlKey && !altKey && arrayIndexOf(keys, evt.keyCode) != -1) {

    if (!shiftKey)
     controller.next(o);
    else
     controller.next(o, true);

    r = false;
  } else {
    if (ctrlKey && (evt.keyCode == 10 || evt.keyCode == 13) && o.name == 'HTMLMemo') {
       o.input.value += '\n';
    }
  }

  if (!r) {
    if (evt.preventDefault) {
      evt.preventDefault();
      evt.stopPropagation();
    } else {
      evt.keyCode = 0;
      evt.returnValue = false;
      evt.cancelBubble = true;
    }
    return false;
  } else
    return true;

}

function markField(obj, type, canSelectOnFocus) {
  if (obj && obj.style && type != 'a') {
    backaux = obj.style.backgroundColor;
    obj.style.backgroundColor = "";
    obj.className=type+'Mark';
    if (obj.select && canSelectOnFocus)
      obj.select();
  }
}

function unmarkField(obj, type, canSelectOnFocus) {
  if (obj && obj.style && type != 'a') {
    obj.className=type;
    if (backaux != "")
      obj.style.backgroundColor = backaux;
    if (obj.unselect && canSelectOnFocus)
      obj.unselect();
  }
}

function findNode(node, name) {
  var r = null;
  var id = node.id || node.name;
  if (id == name) r = node;
  if (!r) {
    for (var i = 0;i < node.childNodes.length; i++) {
      r = findNode(node.childNodes.item(i), name);
      if (r) break;
    }
  }
  return r;
}

var TABLE = 0;
var CELLS = 1;
var ROWS  = 2;
function getTable(rows, cols, width, height) {
  var start = new Date().getTime();

  var lines = new Array(rows);
  var cells = new Array(rows);
  var table = document.createElement("table");
  var tbody = document.createElement("tbody");
  table.appendChild(tbody);
  table.setAttribute('border', 0);
  table.setAttribute('cellSpacing', 0);
  table.setAttribute('cellPadding', 0);

  if (width) table.setAttribute('width', width);
  if (height) table.setAttribute('height', height);

  for (var i=0;i<rows;i++) {
    cells[i] = new Array(cols);
    var tr = document.createElement("tr");
    tbody.appendChild(tr);
    lines[i] = tr;
    for (var j=0;j<cols;j++) {
      cells[i][j] = document.createElement("td");
      tr.appendChild(cells[i][j]);
    }
  }

  return [table, cells, lines];
}

function getInnerTable(rows, cols, width, height) {
  var store = new Array();

  store.push('<table border=0 cellspacing=0 cellpadding=0');
  if (width) store.push(' width='+width);
  if (height) store.push(' height='+height);

  store.push('>');
  for (var i=0; i<50;i++)
  {
          store.push('<tr>');
          for (var j=0;j<50;j++)
          {
                  store.push('<td>');
                  store.push('</td>');
          }
          store.push('</tr>');
  }
  store.push('</table>');
  return store.join('');
}

function getSetTable(e1, e2, width, height) {
  var table = getTable(1, 2, width, height);
  table[CELLS][0][0].appendChild(e1);
  table[CELLS][0][1].appendChild(e2);
  return table[TABLE];
}

function getLabel(description, wordWrap) {
  var label  = document.createElement("font");
  label.className = 'label';
  label.innerHTML = !wordWrap?description.replace(/\s/g, '&nbsp;'):description;
  return label;
}

function pt(v) {
  if (isNumeric(v))
    return v;
  else {
    var r = parseInt(v.replace('px', '').replace('pt', ''));
    if (isNaN(r))
      return document.body.scrollHeight;
    else
      return r;
  }
}

function getDiv(id, x, y, w, h, zindex, visibility) {
  var div = document.createElement("div");
  if (w > 0)  div.style.width = w;

  div.style.height     = h;
  div.style.left       = x+'px';
  div.style.top        = y+'px';
  div.style.position   = 'absolute';
  div.style.zIndex     = zindex;
  div.name             = id;
  if (visibility != null && (visibility==false || visibility=='hide')) {
    div.style.display = 'none';
  } else
    div.style.display = 'block';
  return div;
}

function visibleDiv(div, v) {
  if(div) {
	  if (v) {
	    div.style.display = 'block';
	  } else {
	    div.style.display = 'none';
	  }
  }
}

function isVisibleDiv(div) {
  while (div) {
    if (div.tagName == 'BODY' || !div.style) return true;
    if (div.style.display == 'none')
      return false;
    div = div.parentNode;
  }
  return true;
}

function findPosX(obj)
{
  var curleft = 0;
  if (obj.offsetParent)
  {
    while (obj.offsetParent)
    {
      curleft += obj.offsetLeft - obj.scrollLeft;
      obj = obj.offsetParent;
    }
  }
  else if (obj.x)
    curleft += obj.x;
  return curleft;
}

function findPosY(obj)
{
  var curtop = 0;
  if (obj.offsetParent)
  {
    while (obj.offsetParent)
    {
      curtop += obj.offsetTop - obj.scrollTop;
      obj = obj.offsetParent;
    }
  }
  else if (obj.y)
    curtop += obj.y;
  return curtop;
}

var preloaded = new Array();
function preload(url) {
  if (url && url.length > 0 && !preloaded[url]) {
    var img = new Image(100,100);
    img.src = url;
    preloaded[url] = img;
  }
}

var preloadedscripts;
function loadScript(url, withAjax) {
  if (!preloadedscripts)
    preloadedscripts = new Array();
  if (url && url.length > 0 && !preloadedscripts[url]) {
    if (!withAjax)
      doLoadScript(url);
    else
      doLoadScriptAjax(url);
    preloadedscripts[url] = true;
  }
}

function loadDojo(url) {
  if (!preloadedscripts)
    preloadedscripts = new Array();
  if (url && url.length > 0 && !preloadedscripts[url]) {
    try { dojo.require(url); } catch(e) { }
    preloadedscripts[url] = true;
  }
}

function doLoadScript(url) {
  var oScript = document.createElement('script');
  oScript.setAttribute("type", 'text/javascript');
  oScript.setAttribute("language", 'JavaScript1.2');
  oScript.setAttribute("src", url);
  document.getElementsByTagName('head')[0].appendChild(oScript);

}

var wfr_global = this;
function wfr_eval(/*String*/ scriptFragment){
  return wfr_global.eval ? wfr_global.eval(scriptFragment) : eval(scriptFragment); 	// mixed
}

function doLoadScriptAjax(u) {
  var content = getContent(u);
  lastReceivedContent = content;
  wfr_eval(content);
}

function getTextDiv(text, x, y, color, bgColor, wordWrap) {
    var divText = this.getDiv('', x, y, 0, 0, 6, true);
    divText.style.cursor = 'pointer';
    divText.style.backgroundColor = bgColor;

    var table = getTable(1, 1, '0', '0');
    var label = getLabel(text, wordWrap);
    label.style.color = color;
    table[CELLS][0][0].setAttribute('align', 'center');
    table[CELLS][0][0].setAttribute('valign', 'middle');
    table[CELLS][0][0].appendChild(label);
    divText.appendChild(table[TABLE]);

    return divText;

}

function isNumeric(sText) {

   if (typeof sText == 'number')
     return true;

   sText = ""+sText;

   var ValidChars = "0123456789.";
   var IsNumber=true;
   var Char;

   for (i = 0; i < sText.length && IsNumber == true; i++) {
      Char = sText.charAt(i);
      if (ValidChars.indexOf(Char) == -1) {
         IsNumber = false;
        }
      }
   return IsNumber;
}

function arrayConcat(arr1, arr2) {
  var r = new Array();
  if (arr1) {
    for (var i=0;i<arr1.length;i++)
      r.push(arr1[i]);
  }
  if (arr2) {
    for (var i=0;i<arr2.length;i++)
      r.push(arr2[i]);
  }
  return r;
}