//------------------------------------------------------------------------------
// DomAPI core routines
// D. Kadrioski 3/1/2001
// (c) Nebiru Software 2001-2003
//------------------------------------------------------------------------------
// additional contributors:
// O. Conradi <conradi@cs.utwente.nl>
//------------------------------------------------------------------------------
// special thanks to D. Battini for help with Mac compatibility
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// NOTE: 
// Throughout the library you'll see members prefixed with an underscore.
// these are items that would normally be protected and not published if javascript
// supported such a concept.  Your code should never access these areas.
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// root containers for all domapi related objects.  This effectively reduces 
// global namespace usage to only the keyword "core"
//------------------------------------------------------------------------------
var core                   = {};
core.bags                  = {};
core.comps                 = {};
core.bags.elms             = [];
core.bags.elms.isComponent = false;
//------------------------------------------------------------------------------
// domapi version and unit loader vars
//------------------------------------------------------------------------------
core.copyright  = "(c) Nebiru Software 2001-2003\n"+
                  "All code protected by international copyright law.\n"+
                  "See license.txt for terms and conditions.";
core.version    = "3.01";
core.doDebug    = false; // can cause some functions to give verbose runtime info, also auto includes debug.js
core.doSplash   = false;

if(core.doSplash)core.doSplash = Math.random()*10 < 4;
if(core.doSplash){
  document.write( '<div id="domapi_splash" style="'+
                    'background-color:infobackground;'+
                    'color:infotext;'+
                    'position:absolute;'+
                    (navigator.userAgent.indexOf("MSIE" )>0?'right:18px;':'right:2px;')+
                    'top:3px;'+
                    'white-space:nowrap;'+
                    'border:1px solid threedshadow;'+
                    'font:8pt arial,helvetica,sans-serif;'+
                    'padding:0px 3px;'+
                    '">DomAPI '+core.version+'</div>');
};

//------------------------------------------------------------------------------
// unit locations - for core.loadUnit()
//------------------------------------------------------------------------------
core.libs         = ["core"];
core.libs.extDir  = ["align",
                     "animate",
                     "collision",
                     "color",
                     "cookie",
                     "drag",
                     "form_attach",
                     "groups",
                     "keyboard",
                     "more_css",
                     "more_themes",
                     "more_xbm",
                     "nodesort",
                     "quicksort",
                     "rpccore",
                     "reflow",
                     "resize",
                     "selection",
                     "shadow",
                     "snap",
                     "sysutils",
                     "validate"];
core.libs.objDir  = ["list",
                     "rpcpacket", // loaded automatically by rpccore
                     "xbm"];
core.libs.rootDir = ["component",
                     "core",
                     "corecolor",
                     "coreutil",
                     "css",
                     "debug",
                     "elm",
                     "lang",
                     "loaded",
                     "mozillaext",
                     "theme"];
// all others are assumed to be in /gui
// you can pass relative paths to loadUnit() to move up or down dirs from /gui

//------------------------------------------------------------------------------
// array extensions (additional ones in coreutils.js)
// this one is here becuase this unit needs it
//------------------------------------------------------------------------------
Array.prototype.indexOf = function(s){for(var a=0;a<this.length;a++)if(this[a]==s)return a;return -1};

//------------------------------------------------------------------------------
// code unit loading routines
//------------------------------------------------------------------------------
core.unitLoaded = function(name){return core.libs.indexOf(name)>-1};
//------------------------------------------------------------------------------
core.loadUnit   = function(name){
  if(core.unitLoaded(name))return false; // unit was already loaded, nothing to do
  core.libs[core.libs.length]=name;
  // find subdir
  if(core.libs.rootDir.indexOf(name)>-1)subdir="";else
  if(core.libs.extDir.indexOf( name)>-1)subdir="ext/";else
  if(core.libs.objDir.indexOf( name)>-1)subdir="objs/";else
  subdir="gui/";
  // if we are using compression, add the "_c"
  name+=(core.compressed?"_c":"")+".js";
  // load the script
  document.writeln('<script type="text\/javascript" src="'+core.libPath+subdir+name+'"><\/script>');
};
//------------------------------------------------------------------------------
core._getUnitPath = function(name){ // returns false or the path to the unit
  var r=false;
  var i;
  var re=new RegExp("\/?"+name+"[\._]");
  var tags=document.getElementsByTagName("SCRIPT");
  for(var a=0;a<tags.length;a++){
    i=tags[a].src.search(re);
    if(i>-1)r=tags[a].src.substr(0,i+1);
    if(r && name=="core")core.compressed = tags[a].src.search("_c.js") != -1; 
  }
  return r;
};
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// browser sniffing stuff
//------------------------------------------------------------------------------
core._sniff = function(){
  var c = core;
  var u = navigator.userAgent;
  c.isDom  = document.getElementById;
  c.isMac  = (u.indexOf("Mac"  )>0);
  c.isIE   = (u.indexOf("MSIE" )>0);
  c.isNS   = (u.indexOf("Gecko")>0);
  //-----
  c.isIE5  = false;
  c.isIE50 = false;
  c.isIE55 = false;
  c.isIE6  = false;
  c.isIE60 = false;
  c.isIE7  = false;
  c.isIE70 = false;
  //-----
  c.isNS6  = false;
  c.isNS7  = false;
  //-----
  if(c.isIE){
    var i    = navigator.appVersion.indexOf("MSIE");
    var temp = navigator.appVersion.substring(i+5,i+8);
    c.isIE50   = (temp=="5.0");
    c.isIE55   = (temp=="5.5");
    c.isIE60   = (temp=="6.0");
    c.isIE70   = (temp=="7.0");
    c.isIE5    = temp.charAt(0) == "5";
    c.isIE6    = temp.charAt(0) == "6";
    c.isIE7    = temp.charAt(0) == "7";
  };
  if(c.isNS){
    c.isNS6    = (u.indexOf("Netscape6" )>0||u.indexOf("rv:0.")>0);
    c.isNS7    = (u.indexOf("Netscape/7")>0||u.indexOf("rv:1.")>0);
  }
  c.isIEMac  = c.isMac && c.isIE;
  c.isIE5Mac = c.isMac && c.isIE5;
};
//-------
core._sniff();
//-------
core._checkStrict = function(){
  // taken from http://www.your-site.com/~rinfo/case_studies/doctypes.html
  // mozilla also has a non standard quirks mode http://mozilla.org/docs/web-developer/quirks/
  // ie6 in backcompat mode acts as ie5
  if(core.isIE5Mac)return true; // temporary fix!! we need something better
  var r = false;
  var d = document.doctype;
  r     = (document.compatMode=="CSS1Compat");
  if(d){
    if(d.systemId)
      r = d.systemId.indexOf("strict")>-1;
    else if(d.publicId)
      r = d.publicId.indexOf("transitional")>-1;
  }
  r     = (d&&d.name.indexOf(".dtd")>-1)?true:r;
  return r;
};
core.isStrict    = core._checkStrict();
core.needsBoxFix = (core.isIE5)||(core.isIE60 && !core.isStrict);
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// global constants
//------------------------------------------------------------------------------
core.libPath          = core._getUnitPath(   "core");   // obviously this unit is loaded if this code executes ;)
core.imagePath        = core.libPath       + "gui/images/"; 
core.bodyElm          = function(){return document.body};  
core.cursors          = {};
core.cursors.hand     = core.isIE5?"hand":"pointer";
core.cursors.vertBeam = core.isIE?(core.isIE5?"move":"col-resize"):"move";
core.cursors.horzBeam = core.isIE?(core.isIE5?"move":"row-resize"):"move";
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// load dependancies
//------------------------------------------------------------------------------
core.loadUnit("coreutil"   );
core.loadUnit("css"        );
core.loadUnit("elm"        );
core.loadUnit("theme"      );
core.loadUnit("component"  ); // always load *after* elm and theme, just to be safe
core.loadUnit("corecolor"  );
core.loadUnit("form_attach");
if(core.isNS||core.isIE5Mac)core.loadUnit("mozillaext"); // yes virginia, we need the moz extensions for IE on Mac, long story
if(core.doDebug)            core.loadUnit("debug"     ); // load the debug unit automatically if needed
core.loadUnit("lang"       ); // always load last
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// event support (addEvent() and removeEvent() from D. Battini)
//------------------------------------------------------------------------------
core.addEvent = function(o,t,fn,useCapture){
  /* start M. Proctor's additions */
  if((t == "scroll")&&(!core.isIE)){
    if(!core.scrollEvents)core.scrollEvents = [];
    var e = core.scrollEvents;
    if(e.indexOf(fn) == -1)e[e.length] = fn;
    if(!this.onScrollTimer && core.reflow){
      core.oldPageYOffset = pageYOffset;
      core.oldPageXOffset = pageXOffset;
      core.onfiltered     = setInterval(
        "if((core.reflow.oldPageYOffset!=pageYOffset)||(core.reflow.oldPageXOffset!=pageXOffset))" +
        "{for(var i=0;i<core.scrollEvents.length;i++)core.scrollEvents[i]();" +
        "core.reflow.oldPageYOffset=pageYOffset;core.reflow.oldPageXOffset=pageXOffset;};",25);
    }
    return;
  }
  /* end M. Proctor's additions */
  
  if(o.addEventListener){   // NS/MOZ DOMs evt
    o.addEventListener(t,fn, useCapture);
    return true;
  }else if(o.attachEvent){  // IEs DOMs evt
    var addEvnRt = o.attachEvent("on"+t,fn);
    return addEvnRt;
  }else if(core.isDom && core.isIE5Mac){ // IEs/IE5/51+ MacOS
    o["on"+t] = fn;
  }else
    alert(core.getString("HANDLER_NO_ATTACH")); //curious what this line does?  look in lang.js ;)
};
//------------------------------------------------------------------------------
core.removeEvent = function(o,t,fn,useCapture){
  /* start M. Proctor's additions */
  if((t == "scroll")&&(!core.isIE)){
    var e = core.scrollEvents;
    var i = e.indexOf(fn);
    if(i!=-1)e.deleteItem(i);
    return;
  }
  /* end M. Proctor's additions */
  if(typeof fn == "undefined")return;
  if(o.removeEventListener){ // NS/MOZ DOMs evt
    o.removeEventListener(t,fn, useCapture);
    return true;
  }else if(o.detachEvent){   // IEs DOMs evt
    var remEvnRt = o.detachEvent("on"+t,fn);
    return remEvnRt;
  }else if(core.isDom && core.isIE5Mac){ // IEs/IE5/51+ MacOS
    o["on"+t] = null;
  }else
    alert(core.getString("HANDLER_NO_DETACH"));
};
//------------------------------------------------------------------------------
core.preventBubble = function(E){
  if(core.isIE){
    event.cancelBubble = true;
    event.returnValue  = false;
  }else{
    if(E.stopPropagation)E.stopPropagation();
    else E.preventBubble();
  }
};
//------------------------------------------------------------------------------
onunload = function(){ // Modified by Krister ...
  core._freeAll();
  if(core.doDebug){
    core.debug.closeConsole();
    core.debug.closeProps();
  }
};
//------------------------------------------------------------------------------
core.loadUnit("loaded"); // all done, cleanup before page onload fires
//------------------------------------------------------------------------------