/*  wontofor: A JavaScript shortcut system
 *  Copyright (C) 2010  Niels G. W. Serup
 *
 *  This file is part of wontofor.
 *
 *  wontofor is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  wontofor is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with wontofor.  If not, see <http://www.gnu.org/licenses/>.
 *
 *  Maintained by Niels Serup <ns@metanohi.name>
 *  See <http://metanohi.name/projects/wontofor/>
 */

wontofor = function() {
    this.headElement = document.getElementsByTagName('head')[0]
    this.inclusions = []
    this.inclusionPath = ''
    this.inclusionsInProgress = []
    this.temp = {}
}

wontofor.prototype.dump = function(text) {
    alert(text)
}

wontofor.prototype.setInclusionPath = function(path) {
    if (path.length > 0 && path.substr(path.length-1) != '/')
        path += '/'
    this.inclusionPath = path
}

wontofor.prototype.include = function() {
    if (arguments.length < 1) return
    
    var func = arguments[arguments.length-1]
    
    this.clearCompletedInclusions()
    
    var i
    this.inclusionsInProgress.push([0, -1, null])
    var include_id = this.inclusionsInProgress.length-1
    var num = 0
    var to_be_included = []
    
    for (i = 0; i < arguments.length-1; i++) {
        if (this.inclusions.has(name)) continue
        
        to_be_included.push(i)
        num++
    }
    
    if (num == 0)
        return
    
    this.inclusionsInProgress[include_id] = [num, 0, func]
    for (i = 0; i < num; i++) {
        this.includeOne(arguments[to_be_included[i]], include_id)
    }
}

wontofor.prototype.includeOne = function(name, id) {
    this.temp[name] = function() {}
    this[name] = this.temp[name].prototype
    this[name].root = this
    this[name].name = name
    
    var _this = this
    var elem = document.createElement('script')
    elem.type = 'text/javascript'
    
    elem.onload = function (event) {
        _this.endInclusion(name, id)
    }
    elem.onreadystatechange = function (event) {
        if (js.readyState == 'complete')
            _this.endInclusion(name, id)
    }
    
    elem.src = this.inclusionPath + name + '.js'

    this.headElement.appendChild(elem)
}

wontofor.prototype.endInclusion = function(name, id) {
    if (this.inclusions.has(name)) return
    
    this[name] = new this.temp[name]()
    delete this.temp[name]
    this.inclusions.push(name)
    
    if (this.inclusionsInProgress[id][0] == this.inclusionsInProgress[id][1]+1)
        this.inclusionsInProgress[id][2]()
    this.inclusionsInProgress[id][1]++
}

wontofor.prototype.clearCompletedInclusions = function() {
    var i
    var last_unfinished = -1
    for (i = 0; i < this.inclusionsInProgress.length; i++) {
        if (this.inclusionsInProgress[i][0] != this.inclusionsInProgress[i][1])
            last_unfinished = i
    }
    
    for (i = last_unfinished+1; i < this.inclusionsInProgress.length; i++) {
        this.inclusionsInProgress.pop()
    }
}

Function.prototype.base = function() {
    var _this = this
    var _arguments = arguments
    var _arguments_length = _arguments.length
    return function() {
        var mixed_args = []
        var i = 0
        var arg
        while (i < arguments.length) {
            arg = arguments[i]
            if (arg != null)
                mixed_args.push(arg)
            else if (_arguments_length > i)
                mixed_args.push(_arguments[i])
            else
                mixed_args.push(null)
            i++
        }
        while (i < _arguments.length) {
            mixed_args.push(_arguments[i])
            i++
        }
        return _this.apply(this, mixed_args)
    }
}

Array.prototype.has = function(obj) {
    for (var i = 0; i < this.length; i++) {
        if (this[i] == obj)
            return true
    }
    return false
}

wontofor = new wontofor()
