define('jls/util/Resource', [
  'jls/lang/Class',
  'jls/lang/Exception',
  'jls/lang/Logger',
  'jls/util/XmlElement'
], function (
  Class,
  Exception,
  Logger,
  XmlElement
) {

var Resource;
//Late binding
var Formatter;
require(['jls/util/Formatter'], function(m) {
    Formatter = m;
});

Resource = Class.create( /** @lends jls.util.Resource.prototype */
{
    /**
     * Creates a Resource.
     * 
     * @constructs
     * @class This class provides resource labels.
     */
    initialize : function() {
        this._bundle = {};
    },
    set : function(key, value) {
        if (typeof value == 'undefined') {
            delete this._bundle[key];
        } else {
            this._bundle[key] = value;
        }
        return this;
    },
    /**
     * Returns a label.
     *
     * @param {String} key The label key.
     * @returns {String} The label string.
     */
    get : function(key) {
        if (typeof key != 'string') {
            throw new Exception('Missing key argument');
        }
        if (key in this._bundle) {
            return this._bundle[key];
        }
        return key;
    },
    /**
     * Returns a formatted label.
     *
     * @param {String} key The formatted label key.
     * @returns {String} The formatted label string.
     */
    getf : function(key) {
        var args = Array.from(arguments);
        var key = args.shift();
        var format = this.get(key);
        if (arguments.length < 2) {
            return format;
        }
        args.unshift(format);
        return Formatter.format.apply(Formatter, args);
    }
});

Object.extend(Resource, /** @lends jls.util.Resource */
{
    /**
     * The default resource.
     * @type jls.util.Resource
     */
    DEFAULT: new Resource(),
    loadFromXML : function(xml) {
        if (Logger.getInstance().isTraceEnabled()) {
            Logger.getInstance().trace('loadFromXML("' + xml.toString() + '")');
        }
        var res = new Resource();
        var entries = xml.getChildren();
        for (var i = 0; i < entries.length; i++) {
            var entry = entries[i];
            var key = entry.getAttribute('key');
            if ((entry.getName() == 'entry') && (key != null)) {
                res.set(key, entry.getText());
            }
        }
        return res;
    },
    getPath : function(path, language) {
        if (typeof language == 'undefined') {
            language = _native.core.properties['user.language'];
        }
        return path + '.' + language + '.xml';
    },
    _getResourceAsXML : function(path) {
        if ('boot' in _native) {
            var xml = _native.core.getResourceAsString(path, true);
            return XmlElement.createFromDOM(xml);
        } else {
            var xml = new XML(_native.core.getResourceAsString(path));
            return XmlElement.createFromE4X(xml);
        }
    },
    getResourceAsString : function(path) {
        return _native.core.getResourceAsString(path);
    },
    getResourceAsJSON : function(path) {
    	var s = Resource.getResourceAsString(path);
    	return eval('(' + s + ')');
    },
    /**
     * Loads a resource from an XML path.
     *
     * @param {String} path The path of the XML resource to load.
     * @param {String} [language] The language to use.
     * @returns {jls.util.Resource} The resource.
     */
    load : function(path, language) {
        /*
         * TODO also try to load without language?
         */
        var xml = Resource._getResourceAsXML(Resource.getPath(path, language));
        return Resource.loadFromXML(xml);
    }
});

return Resource;
});
