(function($) {	
	
	var undefined;
	
	var iwc = window.$iwc = function() { };
	
	iwc.fn = iwc.prototype = {
		version: '1.0'
	};
	
	iwc.extend = function(obj, target) {
        if (!target)
            target = this.fn;
        return $.extend(target, obj);
    }
	
	// logging
	iwc.extend({
		log: function(msg) {
            if (typeof(console) != 'undefined') {
                console.log(msg);
            }
        }
	}, iwc.fn);
	
	// frames
	iwc.extend({
		frame: {
			set : function(frameId, source) {
				
				iwc.fn.log("[frame] set : " + source);
				
				var frame = document.getElementById(frameId);
				if (frame == null && document.all != null) {
					document.all[frameId];
				}
				if (frame == null && window.frames != null) {
					frame = window.frames[frameId];
				}
				if (frame != null && source != null) {
					if (frame.contentDocument != null) {
						frame.contentDocument.location.replace(source);
					} else if (frame.contentWindow != null) {
						frame.contentWindow.document.location.replace(source);
					} else {
						frame.src = source;
					}
				}
			}
		}
	}, iwc.fn);
	
	// cookie
	iwc.extend({
		cookie: {
            // code based on: http://www.quirksmode.org/js/cookies.html
            get: function(name, fallback) {
				iwc.fn.log("[cookie] get: "+name);
                var nameEQ = name + "=";
                var ca = document.cookie.split(';');
                for (var i = 0; i < ca.length; i++) {
                    var c = ca[i];
                    while (c.charAt(0) == ' ') c = c.substring(1, c.length);
                    if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
                }
                return fallback ? fallback : undefined;
            },
            set: function(name, value, date /* Date-Object or days */) {
                iwc.fn.log("[cookie] set: "+name + " , " + value);
				var expires = '';
                if (date != undefined) {
                    if (typeof date == 'number') {
                        var dt = new Date();
                        dt.setTime(dt.getTime() + (date * 24 * 60 * 60 * 1000));
                        expires = "; expires=" + dt.toGMTString();
                    }
                    else
                        expires = "; expires=" + date.toGMTString();
                }
                document.cookie = name + "=" + value + expires + "; path=/";
            },
            del: function(name) {
				iwc.fn.log("[cookie] del: "+name);
                this.set(name, "", -1);
            }
        }
	}, iwc.fn);
	
	
	// hash
	iwc.extend({
		hash : {
			_timer: undefined,
			_itemsCache: undefined,
			currentHash: '#',
			isEmpty: function() {
				return this.currentHash == '' || this.currentHash == '#' || this.currentHash == undefined;
			},
			go: function(params) {
				iwc.fn.log("[hash] >>>> go: params");
				iwc.fn.log(params);
				iwc.fn.log("[hash] <<<< go: params");
				var path = '#/';
				if (typeof params != "string") {
					jQuery.each(params, function(indx, el) { path += el + '/'; });
				} else {
					if (!(params.match("/$") == '/')) {
						params += '/';
					}
					path += params;
				}
				iwc.fn.log("[hash] go: path - " + path);
				location.hash = path;
			},
			get: function(indx, fallback) {
				if (!this._itemsCache) {
					iwc.fn.log("[hash] get: load items");
					this._itemsCache = this.currentHash.replace('#', '').split('/');
					jQuery.each(this._itemsCache, function(indx, el) {
						if (el == '') {
							iwc.fn.hash._itemsCache[indx] = undefined;
						}
					});
				}
				var el = this._itemsCache[indx + 1];
				iwc.fn.log("[hash] get: index " + indx + " value " + el);
				iwc.fn.log("[hash] return: " + (el ? "value" : ( fallback ? "fallback" : "fallback - undefined"))); 
				return el ? el : (fallback ? fallback : undefined);
			},
			handleHashTimer: function(callback) {
			
				if (this.currentHash != location.hash) {
					this._itemsCache = undefined;
					this.currentHash = location.hash;
					iwc.fn.log("[hash] handleHashTimer hasChanged");
					// do magic
					if(callback) {
						iwc.fn.log("[hash] handleHashTimer callback");
						callback.call(this, this.currentHash);
					}
				}
			},
			forceLoad : function(callback) {
				iwc.fn.log("[hash] forceLoad");
				
				this.currentHash = undefined;
				this.handleHashTimer(callback);
			},
			init: function(callback) {
				iwc.fn.log("[hash] init!");
				this._timer = setInterval(function() { iwc.fn.hash.handleHashTimer(callback); }, 500); // every 0.5 s
			}
		}
	}, iwc.fn);
		
})(jQuery);