/*
 * cacheImage: a jQuery plugin
 *
 * cacheImage is a simple jQuery plugin for pre-caching images.  The
 * plugin can be used to eliminate flashes of unstyled content (FOUC) and
 * improve perceived page load time.  Callbacks for load, error and abort
 * events are provided.
 *
 * For usage and examples, visit:
 * http://github.com/alexrabarts/jquery-cacheimage
 *
 * Licensed under the MIT:
 * http://www.opensource.org/licenses/mit-license.php
 *
 * Copyright (c) 2008 Stateless Systems (http://statelesssystems.com)
 *
 * @author   Alex Rabarts (alexrabarts -at- gmail -dawt- com)
 * @requires jQuery v1.2 or later
 * @version  0.1

Cache an image:

    $.cacheImage('/path/to/image.png');
    // or if you have images hidden in the DOM:
    $('#myImage').cacheImage();

Cache several images:

    $.cacheImage(['/path/to/an/image.png', '/path/to/another/image.png'])
    // or if you have images hidden in the DOM:
    $('#myImages img').cacheImage();

Add some callbacks:

    $.cacheImage('/path/to/image.png', {
      load : function (e) { console.log('Loaded',  this, e); },
      error: function (e) { console.log('Error',   this, e); },
      abort: function (e) { console.log('Aborted', this, e); }
    });
 */

(function ($) {
	$.extend($, {
		cacheImage: function (src, options) {
			if (typeof src === 'object') {
				$.each(src, function () {
					$.cacheImage(String(this), options);
				});
			}

			var image = new Image();

			options = options || {};

			$.each(['load', 'error', 'abort'], function () { // Callbacks
				var e = String(this);
				if (typeof options[e] === 'function') { $(image)[e](options[e]); }
			});

			image.src = src;

			return image;
		}
	});

	$.extend($.fn, {
		cacheImage: function (options) {
			return this.each(function () {
				$.cacheImage(this.src, options);
			});
		}
	});
})(jQuery);

/*
 * jQuery JSON Plugin
 * version: 1.0 (2008-04-17)
 *
 * This document is licensed as free software under the terms of the
 * MIT License: http://www.opensource.org/licenses/mit-license.php
 *
 * Brantley Harris technically wrote this plugin, but it is based somewhat
 * on the JSON.org website's http://www.json.org/json2.js, which proclaims:
 * "NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.", a sentiment that
 * I uphold.  I really just cleaned it up.
 *
 * It is also based heavily on MochiKit's serializeJSON, which is
 * copywrited 2005 by Bob Ippolito.
 *
var thing = {plugin: 'jquery-json', version: 1.3};

var encoded = $.toJSON(thing);              //'{"plugin": "jquery-json", "version": 1.3}'
var name = $.evalJSON(encoded).plugin;      //"jquery-json"
var version = $.evalJSON(encoded).version;  // 1.3
 */

(function($) {
    function toIntegersAtLease(n)
    // Format integers to have at least two digits.
    {
        return n < 10 ? '0' + n : n;
    }

    Date.prototype.toJSON = function(date)
    // Yes, it polutes the Date namespace, but we'll allow it here, as
    // it's damned usefull.
    {
        return this.getUTCFullYear()   + '-' +
             toIntegersAtLease(this.getUTCMonth()) + '-' +
             toIntegersAtLease(this.getUTCDate());
    };

    var escapeable = /["\\\x00-\x1f\x7f-\x9f]/g;
    var meta = {    // table of character substitutions
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        };

    $.quoteString = function(string)
    // Places quotes around a string, inteligently.
    // If the string contains no control characters, no quote characters, and no
    // backslash characters, then we can safely slap some quotes around it.
    // Otherwise we must also replace the offending characters with safe escape
    // sequences.
    {
        if (escapeable.test(string))
        {
            return '"' + string.replace(escapeable, function (a)
            {
                var c = meta[a];
                if (typeof c === 'string') {
                    return c;
                }
                c = a.charCodeAt();
                return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
            }) + '"';
        }
        return '"' + string + '"';
    };

    $.toJSON = function(o, compact)
    {
        var type = typeof(o);

        if (type == "undefined")
            return "undefined";
        else if (type == "number" || type == "boolean")
            return o + "";
        else if (o === null)
            return "null";

        // Is it a string?
        if (type == "string")
        {
            return $.quoteString(o);
        }

        // Does it have a .toJSON function?
        if (type == "object" && typeof o.toJSON == "function")
            return o.toJSON(compact);

        // Is it an array?
        if (type != "function" && typeof(o.length) == "number")
        {
            var ret = [];
            for (var i = 0; i < o.length; i++) {
                ret.push( $.toJSON(o[i], compact) );
            }
            if (compact)
                return "[" + ret.join(",") + "]";
            else
                return "[" + ret.join(", ") + "]";
        }

        // If it's a function, we have to warn somebody!
        if (type == "function") {
            throw new TypeError("Unable to convert object of type 'function' to json.");
        }

        // It's probably an object, then.
        var ret = [];
        for (var k in o) {
            var name;
            type = typeof(k);

            if (type == "number")
                name = '"' + k + '"';
            else if (type == "string")
                name = $.quoteString(k);
            else
                continue;  //skip non-string or number keys

            var val = $.toJSON(o[k], compact);
            if (typeof(val) != "string") {
                // skip non-serializable values
                continue;
            }

            if (compact)
                ret.push(name + ":" + val);
            else
                ret.push(name + ": " + val);
        }
        return "{" + ret.join(", ") + "}";
    };

    $.compactJSON = function(o)
    {
        return $.toJSON(o, true);
    };

    $.evalJSON = function(src)
    // Evals JSON that we know to be safe.
    {
        return eval("(" + src + ")");
    };

    $.secureEvalJSON = function(src)
    // Evals JSON in a way that is *more* secure.
    {
        var filtered = src;
        filtered = filtered.replace(/\\["\\\/bfnrtu]/g, '@');
        filtered = filtered.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
        filtered = filtered.replace(/(?:^|:|,)(?:\s*\[)+/g, '');

        if (/^[\],:{}\s]*$/.test(filtered))
            return eval("(" + src + ")");
        else
            throw new SyntaxError("Error parsing JSON, source is not valid.");
    };
})(jQuery);

/*
 * get data passed by aplication
 *
 */
(function ($) {
	$.extend($, {
		getAppData: function () {
			return $.evalJSON($('#ijsh').val());
		}
	});
})(jQuery);

/*
 * simple image fader
 *
 */
(function ($) {
	$.extend($, {
		faderController: {
			faderList: new Array(),
			createFader: function(elementId, interval) {
				if(!$.faderController.getFader(elementId)) {
					$.faderController.faderList.push({
						'elementId': elementId,
						'index': 0,
						'list': $('#'+elementId+' img').get().reverse(),
						'interval': interval,
						'timerReference': null
					});
				}
			},
			getFader: function(elementId) {
				for(var x = 0; x < $.faderController.faderList.length; ++x) {
					if($.faderController.faderList[x].elementId = elementId) {
						return $.faderController.faderList[x];
					}
				}

				return false;
			},
			startFader: function(elementId) {
				var faderRef = $.faderController.getFader(elementId);
				if(faderRef) {
					faderRef.timerReference = window.setTimeout(function(){$.faderController.fade(elementId)}, faderRef.interval);
				}
			},
			fade: function(elementId) {
				var faderRef = $.faderController.getFader(elementId);

				if(faderRef) {
					$(faderRef.list[faderRef.index]).css({'opacity': 1, 'z-index': '10'});
					$(faderRef.list).each(function(i){
						if(i != faderRef.index) {
							$(faderRef.list[i]).css({'opacity': 0, 'z-index': '5'});
						}
					});

					if(faderRef.index + 1 < faderRef.list.length) {
						++faderRef.index;
					} else {
						faderRef.index = 0;
					}

					$(faderRef.list[faderRef.index]).css({'z-index': '10'});
					$(faderRef.list).each(function(i){
						if(i != faderRef.index) {
							$(faderRef.list[i]).css({'z-index': '5'});
						}
					});

					$(faderRef.list[faderRef.index]).animate({'opacity': 1}, 1500, 'swing');

					$.faderController.startFader(elementId);
				}
			}
		}
	});

	$.extend($.fn, {
		createFader: function (interval) {
			return this.each(function (i) {
				var eid = $(this).attr('id');
				if(eid) {
					$.faderController.createFader(eid, interval);
					$.faderController.startFader(eid);
				}
			});
		}
	});
})(jQuery);
