;(function($) {
    // private variables
    var oSettings;
    var oUlCss = {};
    var oLiCss = {};
    // default settings
    $.tagcloud = {
        id: "EpiserverEcfTagcloud"
		, version: "0.5.1"
		, defaults: {
		    height: null
			, type: "list"
			, sizemax: 30
			, sizemin: 12
			, colormax: "000000"
			, colormin: "666666"
			, maxcount: 50
		}
    };
    $.fn.extend({
        tagcloud: function(_settings) {
            oSettings = $.extend({}, $.tagcloud.defaults, _settings);

            switch (oSettings.type) {
                case "list":
                    oUlCss = { height: "auto" };
                    oLiCss = { position: "static", display: "inline" };
                    break;
            }

            return this.each(function(i, o) {
                var mUl = $(o);
                var aLi = mUl.find(">li");
                var iNumLi = aLi.length;

                var iUlW = mUl.width();
                var iUlH = oSettings.height === null ? (.004 * iUlW * iNumLi) : oSettings.height;
                mUl.css({ width: iUlW, height: iUlH, listStyle: "none", margin: 0, padding: 0 });
                mUl.css(oUlCss);

                var iValMx = -2147483647;
                var iValMn = 2147483648;
                var iLastVal = -1;
                for (var j = 0; j < iNumLi; j++) {
                    var mLi = $(aLi[j]);
                    var iVal = mLi.attr("value") == -1 ? iLastVal++ : mLi.attr("value");
                    if (iVal > iValMx) iValMx = iVal;
                    if (iVal < iValMn) iValMn = iVal;
                    iLastVal = iVal;
                }
                var iValRn = iValMx - iValMn;

                iLastVal = -1;
                for (var j = 0; j < iNumLi; j++) {
                    var mLi = $(aLi[j]); ;

                    if (j >= oSettings.maxcount) {
                        mLi.remove();
                        continue;
                    }
                    
                    var iVal = mLi.attr("value") == -1 ? iLastVal++ : mLi.attr("value");
                    iLastVal = iVal;
                    //
                    // var fPrt = ((iNumLi - j - 1) / (iNumLi - 1));
                    var fPrt = (iVal - iValMn) / iValRn;
                    //
                    var iSzFnt = oSettings.sizemin + fPrt * (oSettings.sizemax - oSettings.sizemin);
                    var sColor = colorRng(oSettings.colormin, oSettings.colormax, fPrt);
                    //
                    mLi.css({ position: "absolute", margin: 0, padding: 0 });
                    try {
                        mLi.children().css({ "fontSize": iSzFnt, color: "#" + sColor });
                    }
                    catch (ex) { }
                                        
                    var iLiW = mLi.width();
                    var iLiH = mLi.height()
                    //
                    var oCss = {};
                    for (var prop in oLiCss) oCss[prop] = oLiCss[prop];
                    mLi.css(oCss);
                }
            });
        }
    });
    // Park-Miller RNG
    var Rng = new function() {
        this.A = 48271;
        this.M = 2147483647;
        this.Q = this.M / this.A;
        this.R = this.M % this.A;
        this.oneOverM = 1.0 / this.M;
    }

    // hex dec
    function d2h(d) { return d.toString(16); }
    function h2d(h) { return parseInt(h, 16); }

    function getRGB(s) {
        var b3 = s.length == 3;
        var aClr = [];
        for (var i = 0; i < 3; i++) {
            var sClr = s.substring(i * (b3 ? 1 : 2), (i + 1) * (b3 ? 1 : 2));
            aClr.push(h2d(b3 ? sClr + sClr : sClr));
        }
        return aClr;
    }
    function getHex(a) {
        var s = "";
        for (var i = 0; i < 3; i++) {
            var c = d2h(a[i]);
            if (c.length == 1) c = "0" + c; // todo: this can be better
            s += c;
        }
        return s;
    }
    function colorRng(mn, mx, prt) {
        var aMin = getRGB(mn);
        var aMax = getRGB(mx);
        var aRtr = [];
        for (var i = 0; i < 3; i++) aRtr.push(aMin[i] + Math.floor(prt * (aMax[i] - aMin[i])));
        return getHex(aRtr);
    }

    // set functions
    $.fn.TagCloud = $.fn.Tagcloud = $.fn.tagcloud;
})(jQuery);
