
Function.prototype.bind = function() {
    var self = this;
    var args = arguments;
    return function() {
        return self.apply(self, args);
    }
}

StatusWidget = function(id, net) {
    if (net === null) {
        net = new Network();
    }

    this.id = id;
    this.inventory = null;
    this.net = net;

    var self = this;

    net.asyncRequestJson('getStats.json', function(result) {
        self.__setText("name", result.name);
        self.__setText("hit_point_score", result.hit_points);
        self.__setText("kickboxing_score", result.kickboxing);
        self.__setText("linear_algebra_score", result.linear_algebra);
        self.__setText("cross_stitching_score", result.cross_stitching);
    });

    this.__getChild("equipment").onclick = function() {
        self.toggleInventoryDisplay();
    };
};

StatusWidget.prototype = {
    toggleInventoryDisplay : function() {
        var n = this.__getChild("inventory");
        if (n.style['display'] == 'block') {
            n.style['display'] = 'none';
        } else {
            this.__showInventory();
        }
    },
    
    __showInventory : function() {
        var n = this.__getChild("inventory");
        n.style['display'] = 'block';
        if (this.inventory === null) {
            var self = this;
            this.net.asyncRequestJson('getInventory.json', function(inventory) {
                self.__renderInventory(inventory);
                self.inventory = inventory;
            });
        }
    },

    __renderInventory : function(inventory) {
        var n = this.__getChild('inventory');
        while (n.firstChild) {
            n.removeChild(n.firstChild);
        }

        for (var index in inventory) {
            var i = inventory[index];
            var li = document.createElement('li');
            li.setAttribute('class', 'inventory-item item-' + index);
            li.innerHTML = i.name;
            li.onclick = function(self, index) {
                self.__equipItem(index);
            }.bind(this, index);
            n.appendChild(li);
        }
    },

    __equipItem : function(index) {
        this.net.post('updateEquipment.php', {name:this.inventory[index].name});
    },

    __getChild : function(className) {
        var xpath = "//div[@id='" + this.id + "']//*[@class='" + className + "']";
        var i = document.evaluate(
            xpath, document, null, XPathResult.ANY_TYPE, null
        );
        return i.iterateNext();
    },

    __setText : function(classname, value) {
        var c = this.__getChild(classname);
        c.innerHTML = value;
    },

    __getInt : function(className) {
        return parseInt(this.__getChild(className).innerHTML);
    },

    getName : function() {
        return this.__getChild("name").innerHTML;
    },

    getHitPoints : function() {
        return this.__getInt("hit_point_score");
    },

    getKickboxingScore : function() {
        return this.__getInt("kickboxing_score");
    },

    getLinearAlgebraScore : function() {
        return this.__getInt("linear_algebra_score");
    },

    getCrossStitchingScore : function() {
        return this.__getInt("cross_stitching_score");
    }
};

function Network() {
}

Network.prototype = {
    asyncRequestJson : function (url, onComplete) {
        var req = new XMLHttpRequest();
        req.onreadystatechange = function() {
            if (req.readyState == 4) {
                if (req.status == 200) {
                    var result = jsonParse(req.responseText);
                    onComplete(result);
                } else {
                    throw new Error("Request failed: " + req.status);
                }
            }
        }

        req.open('GET', url, true);
        req.send(null);
    },
    
    post : function(url, data, onComplete) {
        // Implementation left as an exercise to the reader :D
    }
}