snow = {};

/* constants */
snow.E_NOTICE = 1;
snow.E_WARNING = 2;
snow.E_FATAL = 4;
snow.HOME = '';

snow.URI =
{
    'self'      :   'index.php'
};

// for inheritance sugar
// flag indicates we just want the object for it's prototype - don't actually initialize it
snow.PURE = '_pure';

// these are events that the PageController will 
// watch for and dispatch
snow.catch_events = new Array('onclick', 'onchange');

// libraries loaded. cf. snow.use()
snow.loaded_libs = Array();
snow.load_requests = Array();

// timer for checking script loading
snow.load_interval;

snow.init = function()
{
    var c = new snow.PageController();

    // register events
    for (var i = 0, len = snow.catch_events.length; i < len; i++)
    {
        document[snow.catch_events[i]] = function(evt) { c.main(evt); };
    }
}

snow.destroy = function()
{
    for (var i = 0, len = snow.catch_events.length; i < len; i++)
    {
        document[snow.catch_events[i]] = null;
    }
}

snow.use = function()
{
    for (var i = 0; i < arguments.length; i++)
    {
        var lib = arguments[i];

        snow.load_requests.push(lib);

        var els = lib.split('.');
        var class_name = els.pop();

        var url = '';
        if (snow.HOME)
        {
            url = snow.HOME + '/';
        }

        var lib_name = els[els.length - 1];
        var namespace = 'window["' + els.join('"]["') + '"]';

        // load the entire library
        if (class_name == '*')
        {
            url += els.join('/') + '/' + lib_name + '.lib.js';
        }
        // just load one class file
        else
        {
            url += els.join('/') + '/' + class_name + '.class.js';

            // need the class name back on for namespace initialization, below
            els.push(class_name);
        }

        var ns = 'window';
        // create namespace
        // make sure all the parents are set
        var loaded = true;
        for (var i in els)
        {
            ns += '["' + els[i] + '"]';

            if (eval(ns) == undefined)
            {
                eval(ns + ' = {}');
                loaded = false;
            }
        }

        // because snow.class.js must be loaded via a script tag,
        // and the snow namespace is already defined, we need to keep
        // track of this one ourselves. otherwise
        // snow.use('snow.*')
        // won't work
        if (!loaded || lib == 'snow.*' && snow.self_loaded == undefined)
        {
            var script = createEl('script');
            script.src = url;
            script.type = 'text/javascript';
            document.getElementsByTagName('head')[0].appendChild(script);

            if (lib == 'snow')
            {
                snow.self_loaded = true;
            }
        }
    }
    var loader = new snow.Loader(arguments);
    return loader;
}

snow.register = function(lib)
{
    snow.loaded_libs[lib] = true;
}

/* snow.Loader
 * used by snow to fire functions when a snow.use() call completes
 */
snow.Loader = function(libs)
{
    this.libs = libs;
}
// make sure we have a unique id,
// even if the same libs are loaded
snow.Loader.id_increment = 0;

snow.Loader.timer = Array();

snow.Loader.prototype.whenLoaded = function(func)
{
    var libs = this.libs;
    var id = '';
    for (var i = 0; i < libs.length; i++)
    {
        id += libs[i];
    }
    id += snow.Loader.id_increment++;

    var isLoaded = function()
    {
        for (var i = 0; i < libs.length; i++)
        {
            if (!snow.loaded_libs[libs[i]])
            {
                return false;
            }
        }
        // here, everything's in
        clearInterval(snow.Loader.timer[id]);
        func();
    }

    snow.Loader.timer[id] = setInterval(isLoaded, 100);
}


window.onunload = snow.destroy;
