﻿//<using>
//  nui/nui.js
//</using>

/**
 * NUI.Lang -- Provides the language utilites and extensions used by the NUI library.
 * Copyright 2007, NetRanking.cn
 *
 * @class NUI.Lang
 */
NUI.Lang = {
    isNumber : function(vValue) {
        return typeof(vValue) === "number";
    },
    isBoolean : function(vValue) {
        return typeof(vValue) === "boolean";
    },
    isFunction : function(vValue) {
        return typeof(vValue) === "function";
    },
    isString : function(vValue) {
        return typeof(vValue) === "string";
    },
    isUndefined : function(vValue) {
        return typeof(vValue) === 'undefined';
    },
    isNull : function(vValue) {
        return vValue === null;
    },
    isObject : function(vValue) {//null is not object! array and function are objects!
        return (vValue && (typeof(vValue) === 'object' || NUI.Lang.isFunction(vValue))) || false;
    },
    isArray : function(vValue) { 
        if (vValue) {
           var l = NUI.Lang;
           return l.isNumber(vValue.length) && l.isFunction(vValue.splice);
        }
        return false;
    },
    
    /**
     * Date format
     */
    DateFormat : (function() {
        /*
         * Date Format 1.2.2
         * (c) 2007-2008 Steven Levithan <stevenlevithan.com>
         * MIT license
         * Includes enhancements by Scott Trenda <scott.trenda.net> and Kris Kowal <cixar.com/~kris.kowal/>
         * http://blog.stevenlevithan.com/archives/date-time-format
         *
         * Accepts a date, a mask, or a date and a mask.
         * Returns a formatted version of the given date.
         * The date defaults to the current date/time.
         * The mask defaults to dateFormat.masks.default.
         */
        var _dateFormat = function () {
	        var	token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
		        timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
		        timezoneClip = /[^-+\dA-Z]/g,
		        pad = function (val, len) {
			        val = String(val);
			        len = len || 2;
			        while (val.length < len) val = "0" + val;
			        return val;
		        };

	        // Regexes and supporting functions are cached through closure
	        return function (date, mask, utc) {
		        var dF = NUI.Lang.DateFormat;

		        // You can't provide utc if you skip other args (use the "UTC:" mask prefix)
		        if (arguments.length == 1 && (typeof date == "string" || date instanceof String) && !/\d/.test(date)) {
			        mask = date;
			        date = undefined;
		        }

		        // Passing date through Date applies Date.parse, if necessary
		        date = date ? new Date(date) : new Date();
		        if (isNaN(date)) throw new SyntaxError("invalid date");

		        mask = String(dF.masks[mask] || mask || dF.masks["default"]);

		        // Allow setting the utc argument via the mask
		        if (mask.slice(0, 4) == "UTC:") {
			        mask = mask.slice(4);
			        utc = true;
		        }

		        var	_ = utc ? "getUTC" : "get",
			        d = date[_ + "Date"](),
			        D = date[_ + "Day"](),
			        m = date[_ + "Month"](),
			        y = date[_ + "FullYear"](),
			        H = date[_ + "Hours"](),
			        M = date[_ + "Minutes"](),
			        s = date[_ + "Seconds"](),
			        L = date[_ + "Milliseconds"](),
			        o = utc ? 0 : date.getTimezoneOffset(),
			        flags = {
				        d:    d,
				        dd:   pad(d),
				        ddd:  dF.i18n.dayNames[D],
				        dddd: dF.i18n.dayNames[D + 7],
				        m:    m + 1,
				        mm:   pad(m + 1),
				        mmm:  dF.i18n.monthNames[m],
				        mmmm: dF.i18n.monthNames[m + 12],
				        yy:   String(y).slice(2),
				        yyyy: y,
				        h:    H % 12 || 12,
				        hh:   pad(H % 12 || 12),
				        H:    H,
				        HH:   pad(H),
				        M:    M,
				        MM:   pad(M),
				        s:    s,
				        ss:   pad(s),
				        l:    pad(L, 3),
				        L:    pad(L > 99 ? Math.round(L / 10) : L),
				        t:    H < 12 ? "a"  : "p",
				        tt:   H < 12 ? "am" : "pm",
				        T:    H < 12 ? "A"  : "P",
				        TT:   H < 12 ? "AM" : "PM",
				        Z:    utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""),
				        o:    (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
				        S:    ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
			        };

		        return mask.replace(token, function ($0) {
			        return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
		        });
	        };
        }();
        
        // For convenience...
        Date.prototype.format = function (mask, utc) {
	        return _dateFormat(this, mask, utc);
        };

        return {
            masks : {
	            "default":      "ddd mmm dd yyyy HH:MM:ss",
	            shortDate:      "m/d/yy",
	            mediumDate:     "mmm d, yyyy",
	            longDate:       "mmmm d, yyyy",
	            fullDate:       "dddd, mmmm d, yyyy",
	            shortTime:      "h:MM TT",
	            mediumTime:     "h:MM:ss TT",
	            longTime:       "h:MM:ss TT Z",
	            isoDate:        "yyyy-mm-dd",
	            isoTime:        "HH:MM:ss",
	            isoDateTime:    "yyyy-mm-dd'T'HH:MM:ss",
	            isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
            },
            i18n : {
	            dayNames: [
		            "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
		            "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
	            ],
	            monthNames: [
		            "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
		            "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
	            ]
            },
            format : function(vDate, mask, utc) {
                return _dateFormat(vDate, mask, utc);
            }
        };
    })(),
    
    /**
     * Get an unique int to used as an id
     * @return {int}
     */
    getUniqueId : (function() {
        var g_minId = 0, g_maxId = 4294967295;
        
        return function() {
            var count = 0;
            if(g_minId >= g_maxId){
                NUI.Widget.Alert("Error : can not get legal unique id");
                return null;
            }
            g_minId ++;
            return g_minId;
        };
    })()
};

