/* @package xcap ************************************************************ */

/**
 * @fileoverview The XCAP base package.
 *
 * @version $Id: xcap.js,v 1.1 2008/09/12 10:57:13 johanna Exp $
 */
 
/**
 * @class Abstract base class in the <code>xcap</code> package.
 *
 * @constructor
 *
 * @return <span style="color: red;">Abstract class, should not be instantiated</span>
 */
xcap = function()
{
	// Keep for JSDoc
};

/**
 * The current version of the <code>xcap</code> JavaScript package.
 * 
 * @type String
 */
xcap.version = '2.0';

/**
 * Collection of translations.
 *
 * @private
 * @type Array
 */
xcap.translations = {};

/**
 * Returns a translated text from a localized text resource collection, or if 
 * the text can't be found the request string, describing 
 * <code>[prefix[.lang[_Country]].]key</code>.
 * 
 * <p>If a localized resource can't be found, the function will look for the
 * text in the default collection instead. If the language code is specific to 
 * both a language and country, and no match is found, the resource for just the
 * language part of the code will be tried for a match.</p>
 *
 * <p>Omitting or passing any expression that does <strong>not</strong> evaluate
 * to <code>true</code> as the <code>prefix</code> will be interpreted as an 
 * empty string prefix.</p>
 *
 * <strong>Usage example:</strong>
 * <pre>
 *    var loginMessage = xcap.getText('chat', 'login', 'sv_SE');
 * </pre>
 *
 * @param prefix 	The translations module prefix
 * @param key 		A specific text key to get
 * @param lang 		Optional language or locale code, for example <code>sv_SV</code>
 *
 * @author Jens Askengren jens@josh.se
 * @author Olle Törnström olle@josh.se
 *
 * @return The translated text or a the text request string: <code>[prefix[.lang[_Country]].]key</code>
 * @type String
 */
xcap.getText = function(/*String*/ prefix, /*String*/ key, /*String*/ lang)
{
	if (!prefix)
		prefix = '';

	var resource = xcap.translations[prefix];
	
	if (resource)
	{
	    var l = null;

	    if (lang)
	    {
	        l = resource[lang];
	        
	        if (l === undefined)
	        {
	            var i = lang.indexOf('_');
	            
	            if (i != -1)
	            {    
	                l = resource[lang.substring(0, i)];
	            }
	        }
	    }
	    
	    if (l === undefined || l === null)
	    {
	        l = resource;
	    }
	    
	    var v = l[key];
	    
	    if (v)
	    {
	        return v;
	    }            
	}
	
	return (prefix ? prefix + '.' : '') + (lang ? lang + '.' : '') + key;
};

/**
 * Add translations, localized into collections by language. If a translation 
 * is added without any language code it will be considered the 
 * <strong>default</strong>.<br /><br />
 *
 * <strong>Usage example:</strong>
 * <pre>
 *    xcap.addTexts('chat', {'login' : 'Login'});
 *
 *    // Localized for swedish
 *    xcap.addTexts('chat', {'login' : 'Logga in'}, 'sv_SE');
 * </pre>
 *
 * @author Jens Askengren jens@josh.se
 * @author Olle Törnström olle@josh.se
 *
 * @param prefix		The translations module prefix
 * @param translations 	Maps from key to translated value, for example <code>{'date' : 'Datum', 'name' : 'Namn'}</code>
 * @param lang 			Optional language code, for example <code>sv_SE</code> or just <code>sv</code>
 */
xcap.addTexts = function(/*String*/ prefix, /*String*/ translations, /*String*/ lang)
{
	if (!prefix)
		prefix = '';

    if (lang)
    {
        if (xcap.translations[prefix] === null)
        {
            xcap.translations[prefix] = {};
        }
        
        xcap.translations[prefix][lang] = translations;
    }
    else
    {
        xcap.translations[prefix] = translations;
    }
};


/**
 * Extends one class with the prototype of another. This enforces a model
 * for working class based ineritance in JavaScript, also known as object
 * orientation.
 *
 * <h3>Quick reference</h3>
 *
 * <p>Syntax for class extension:</p>
 * <pre>
 *    xcap.extend([SubClass], [SuperClass]);
 * </pre>
 * <p>Syntax for super class construtor calling:</p>
 * <pre>
 *    [SubClass].superConstructor.call(this [, args]);
 * </pre>
 * <p>Syntax for super class method calling:</p>
 * <pre>
 *    [SubClass].superClass.[methodName].call(this [, args]);
 * </pre> 
 *
 * <h3>Description</h3>
 *
 * <p>The <code>extends()</code> call needs to be placed directly 
 * <strong>after</strong> the class constructor in order to work. Also calling 
 * of the super class constructor in the class constructor of the extending 
 * class is needed for properties to be initalized.</p>
 *
 * <p>Extending with this method defines two members that connects the super
 * with it's extending sub class:</p>
 * <ul>
 *    <li>
 *       <code>superConstructor</code> - The constructor method of the super 
 *       class. Enabling calling in any sub class constructor, like this:
 *       <pre>
 *          Super = function(foo)
 *          {
 *             // Some foo handling in constructor
 *          };
 * 
 *          Sub = function(foo, bar)
 *          {
 *             Sub.superConstructor.call(this, foo);
 *             // Some bar handling in constructor
 *          };
 *          xcap.extend(Sub, Super);
 *       </pre>
 *       <p>NOTE: The use of <code>this</code> in the 
 *       <code>superConstrutcor.call()</code> is needed for reference to the sub
 *       class prototype member.</p>
 *    </li>
 *    <li>
 *       <code>superClass</code> - The super class itself, making any method
 *       of the super class available for calling in overriding methods, like
 *       this:
 *       <pre>
 *          Super.prototype.dooFoo = function(foo)
 *          {
 *             // Does something with foo
 *          };
 * 
 *          // Extending the method in Super
 *          Sub.prototype.dooFoo = function(foo, bar)
 *          {
 *             Sub.superClass.dooFoo.call(this, foo);
 *             // Does something with bar too
 *          };
 *       </pre>
 *       <p>NOTE: The use of <code>this</code> in the 
 *       <code>superClass.call()</code> is needed for reference to the sub
 *       class prototype member.</p>
 *    </li>
 * </ul>
 *
 * @author Olle Törnström olle@josh.se
 *
 * @param {Object} subClass A JavaScript class that will be extended
 * @param {Object} superClass A JavaScript super class, extending the sub class
 * @return The extended class {Object}
 */
xcap.extend = function(subClass, superClass)
{
	Inherit = function() { };
	Inherit.prototype = superClass.prototype;
	
	subClass.prototype = new Inherit();
	subClass.prototype.constructor = this;
	subClass.superConstructor = superClass;
	subClass.superClass = superClass.prototype;
	
	return subClass;
};


/**
 * Decorates one instance with the properties of another, if they're not
 * already initialized. This enables a property based model for instance
 * inheritance.
 *
 * Usage:
 * <pre>
 *   A = function() {
 *      this.name  = 'A';
 *      this.color = 'blue';
 *   };
 *
 *   B = function() {
 *      xcap.decorate(this, new A());
 *      this.name = 'B';
 *   };
 * </pre>
 * 
 * <p>Any instance of new B will now also have the color property defined in A.</p>
 *
 * @author Olle Törnström olle@josh.se
 *
 * @param target The instance to decorate.
 * @param source The decorator source.
 * @param override Override existing properties or not, defaults to <code>>false</code>.
 */
xcap.decorate = function(/*Object*/ target, /*Object*/ source, /*boolean*/ override)
{
	var _override = (override !== undefined) ? override : false;

	for (var property in source)
	{
		if (property !== 'prototype' && _override)
		{
			target[property] = source[property];
		}
		else if (property !== 'prototype' && target[property] === undefined)
		{
			target[property] = source[property];
		}
	}
};
