/*jslint browser: true, devel: true, evil: true, forin: true */
/* Simple JavaScript Inheritance
 * By John Resig http://ejohn.org/
 * Copied from http://ejohn.org/blog/simple-javascript-inheritance/
 * MIT Licensed.
 */
// Inspired by base2 and Prototype
(function (){
    var initializing = false, fnTest = /xyz/.test(function (){
        xyz;
    }) ? /\b_super\b/ : /.*/;
    this.Class = function (){};
    Class.extend = function (prop){
        var _super = this.prototype;
        initializing = true;
        var prototype = new this();
        initializing = false;
        for (var name in prop) {
            prototype[name] = typeof prop[name] == "function" &&
            typeof _super[name] == "function" &&
            fnTest.test(prop[name]) ? (function (name, fn){
                return function (){
                    var tmp = this._super;
                    this._super = _super[name];
                    var ret = fn.apply(this, arguments);
                    this._super = tmp;
                    return ret;
                };
            })(name, prop[name]) : prop[name];
        }
        function Class(){
            if (!initializing && this.init) 
                this.init.apply(this, arguments);
        }
        Class.prototype = prototype;
        Class.constructor = Class;
        Class.extend = arguments.callee;
        return Class;
    };
})();

/*
 * Extensiones de jQuery
 */
jQuery(function() {
    jQuery.support.borderRadius = false;
    jQuery.each(['borderRadius','MozBorderRadius','WebkitBorderRadius','OBorderRadius','KhtmlBorderRadius'], function() {
        if(document.body.style[this] !== undefined) jQuery.support.borderRadius = true;
        return (!jQuery.support.borderRadius);
    });
	
	jQuery.support.columnCount = false;
	jQuery.each(['columnCount', 'MozColumnCount', 'WebkitColumnCount', 'OColumnCount', 'KhtmlColumnCount'], function () {
		if(document.body.style[this] !== undefined) jQuery.support.columnCount = true;
		return (!jQuery.support.columnCount);
	});
	
	jQuery.fn.extend({
		cycleNext: function (sel) {
			var ret  = this.next(sel);
			return ret.size()?ret:this.parent().children(sel).first();
		},
		cyclePrev: function (sel) {
			var ret  = this.prev(sel);
			return ret.size()?ret:this.parent().children(sel).last();
		}
	});
});

/*
 * Gestion de cookies
 */
/**
 * Gets the value of a cookie by its name.
 * @param {String} name
 *     The name of the cookie
 * @return
 *     A String with the value of the cookie or Null if the cookie does not exist. 
 */
function getCookie(name){
    var start = document.cookie.indexOf(name + "="), len = start + name.length + 1, end;
    if ((!start) && (name !== document.cookie.substring(0, name.length))) {
        return null;
    }
    if (start === -1) {
        return null;
    }
    end = document.cookie.indexOf(';', len);
    if (end === -1) {
        end = document.cookie.length;
    }
    return unescape(document.cookie.substring(len, end));
}

/**
 * Sets a new cookie or overrides a previously existing one.
 * @param {String}  name
 *     The name of the cookie
 * @param {String}  value
 *     The value to be set
 * @param {Number}  expires
 *     Days for the cookie to be valid, this is an optional parameter.
 * @param {String}  path
 *     Path in which the cookie is to be used, this is an optional parameter.
 * @param {String}  domain
 *     Domain in which the cookie is to be used, this is an optional parameter.
 * @param {Boolean}
 *     secure  Set to true if the cookie is used within a HTTPS protocol.
 */
function setCookie(name, value, expires, path, domain, secure){
    var today = new Date(), expires_date;
    today.setTime(today.getTime());
    if (expires) {
        expires = expires * 1000 * 60 * 60 * 24;
    }
    expires_date = new Date(today.getTime() + (expires));
    document.cookie = name + '=' + escape(value) + ((expires) ? ';expires=' + expires_date.toGMTString() : '') + ((path) ? ';path=' + path : '') + ((domain) ? ';domain=' + domain : '') + ((secure) ? ';secure' : '');
}

/**
 * Deletes a cookie by its name and, optionally, by its path or domain.
 * @param {String} name
 *     The name of the cookie
 * @param {String} path
 *     Path of the cookie to be deleted, this is an optional parameter.
 * @param {String} domain
 *     Domain of the cookie to be deleted, this is an optional parameter.
 */
function deleteCookie(name, path, domain){
    if (getCookie(name)) {
        document.cookie = name + '=' + ((path) ? ';path=' + path : '') + ((domain) ? ';domain=' + domain : '') + ';expires=Thu, 01-Jan-1970 00:00:01 GMT';
    }
}

/*
 * Manipulacion de hojas de estilo
 */
/**
 * Finds a CSS rule in all style sheets.
 * @param {String}  sRuleName
 *     The selector to be found.
 * @param {Boolean} deleteFlag
 *     If this is set to true, the CSS rule is deleted.
 *     Do not set this parameter to true, instead use killCSSRule. 
 * @see
 *     killCSSRule
 * @return
 *     The CSS rule Object or False if the rule is not found.
 */
function getCSSRule(sRuleName, deleteFlag){
    var styleSheet,cssRule,i,ii;
	ruleName = sRuleName.toLowerCase();
    if (document.styleSheets) {
        for (i = 0; i < document.styleSheets.length; i++) {
            styleSheet = document.styleSheets[i];
            ii = 0;
            cssRule = false;
            do {
                if (styleSheet.cssRules) {
                    cssRule = styleSheet.cssRules[ii];
                }
                else {
                    cssRule = styleSheet.rules[ii];
                }
                if (cssRule && cssRule.selectorText) {
                    if (cssRule.selectorText.toLowerCase() === ruleName) {
                        if (deleteFlag === 'delete') {
                            if (styleSheet.cssRules) {
                                styleSheet.deleteRule(ii);
                            }
                            else {
                                styleSheet.removeRule(ii);
                            }
                            return true;
                        }
                        else {
                            return cssRule;
                        }
                    }
                }
                ii++;
            }
            while (cssRule);
        }
    }
    return false;
}
/**
 * Removes a CSS rule from the style sheet it is in.
 * @param {String} ruleName
 *     The selector to be deleted.
 * @return
 *     True if the CSS rule was deleted correctly,
 *     False if it was not found within the style sheets.
 * @type Boolean
 */
function killCSSRule(ruleName){
    return getCSSRule(ruleName, 'delete');
}
/**
 * Creates an empty CSS rule in the first style sheet of the document.
 * @param {String} ruleName
 *     The selector of the CSS rule to be created.
 * @return
 *     The CSS rule Object.
 */
function addCSSRule(ruleName){
    if (document.styleSheets) {
        if (!getCSSRule(ruleName)) {
            if (document.styleSheets[0].addRule) {
                document.styleSheets[0].addRule(ruleName, null, 0)
            }
            else {
                document.styleSheets[0].insertRule(ruleName + ' { }', 0)
            }
        }
    }
    return getCSSRule(ruleName)
}

/*
 * Management of extensions and events.
 * 
 * If an element needs to be formatted or has an event attached on its creation
 * we use an HttpCom.extensions function in order to execute it.
 * 
 * In a similar way, if a function creates new DOM elements, they have to be extended
 * through the HttpCom.extend().
 */
var HttpCom = {};
HttpCom.extensions = {};
HttpCom.extend = function (scope) {
	var actualScope = scope || document,i;
	for (i in this.extensions) {
		this.extensions[i](actualScope);
	} 
}

/*
 * Usage of HttpCom.extensions:
 * We use the extensions to add some clases to list-like elements.
 */
HttpCom.extensions.addListClasses = function (scope) {
	var $el = $('li, tr', scope);
	$el.filter(':first-child').addClass('first');
	$el.filter(':last-child').addClass('last');
	$el.filter(':nth-child(2n+1)').addClass('odd').next().addClass('even');
};

/*
 * Extension to adjust the #nav children elements' width 
 */
HttpCom.extensions.setNavElementsWidth = function (scope) {
	var $nav = $('#nav', scope),
		$ul = $nav.find('ul'),
		$li = $nav.find('li'),
        nLiIndex,
        nCurrWidth = 0,
        nMaxWidth = $ul.parent().width() || 0;
	$li.each(function (index) {
		var $t = $li.eq(index);
        nCurrWidth += (
            parseInt($t.css('marginLeft'), 10) +
			parseInt($t.css('paddingLeft'), 10) +
			parseInt($t.width(), 10) +
			parseInt($t.css('paddingRight'), 10) +
			parseInt($t.css('marginRight'), 10)
		);
	});
	while (nCurrWidth < nMaxWidth) {
		nLiIndex = nCurrWidth % $li.length;
		$li.eq(nLiIndex).width($li.eq(nLiIndex).width() + 1);
		nCurrWidth++;
	}
	// fix Zoom resizing
	$nav.css({
		width:nMaxWidth + 'px',
		overflow: 'hidden'
	});
	$ul.width(nMaxWidth*2);
	// fix positioning in IE7
	if ($.browser.msie && $.browser.version < 8) {
		$('#book', scope).before('<div style="clear:both;width:100%;height:0;"></div>')
	}
};
HttpCom.extensions.setFooterLogosWidth = function (scope) {
	var $li = $('#footer li', scope);
	$li.width([Math.floor(100/$li.length), '%'].join('')); 
}

/*
 * Handle fixed-tab show and removal
 */
HttpCom.extensions.fixedTabRemoval = function (scope) {
	$('div.fixed-tab a.close', scope).click(function () {
		var $tab = $(this).closest('.fixed-tab');
		$tab.slideUp(200);
	});
}
$(function () {
	// only once!
	var $book = $('#book'),
		nWindow = 50;
	if (!$book.length) {
		return;
	}
	function showTabs() {
		if ($(window).scrollTop() > $book.height() + $book.offset().top + nWindow) {
			$('div.fixed-tab').slideDown();
			$(window).unbind('scroll', showTabs);
			$(window).bind('scroll', reassignShowTabs);
		}
	};
	function reassignShowTabs() {
		if ($(window).scrollTop() < $book.height() + $book.offset().top - nWindow) {
			$(window).unbind('scroll', reassignShowTabs);
			$(window).bind('scroll', showTabs);
		}
	}
	$(window).bind('scroll', showTabs); 
});

/*
 * Cycle through opinions
 */
HttpCom.extensions.cycleOpinions = function (scope) {
	$('div.cycle-comments', scope).each(function () {
		var $t = $(this),
			$opinions = $t.children('blockquote'),
			disableClass = 'disabled';
			
		if ($opinions.length > 1) {
			$opinions.not(':first').hide();
			$t.find('div.cycle-controls').find('a').click(function () {
				var $t = $(this),
					sDir = $(this).hasClass('prev') ? 'prev' : 'next',
					$current = $opinions.filter(':visible'),
					$toShow = $current[sDir]('blockquote');
				if ($toShow.length && !$t.is('.disabled')) {
					// deactivate link in case there are no more opinions
					if (!$toShow[sDir]('blockquote').length) {
						$t.addClass(disableClass);
					}
					$t.siblings('a').removeClass(disableClass);
					// and launch animation 
					$current.hide('slide', {direction:sDir==='prev'?'right':'left'}, 400);
					$toShow .show('slide', {direction:sDir==='prev'?'left':'right'}, 400);
				} 
				
			}).eq(0).addClass(disableClass);
		} else {
			$t.find('div.cycle-controls').hide();
		}
	});
}

/*
 * Column layout for non supporting browsers
 */
jQuery(function ($) {
	if (!jQuery.support.columnCount) {
		HttpCom.extensions.columnLayoutForLists = function (scope) {
			var reClassName = /text-(\d)-columns/g;
			$('ul, ol', scope).filter(function () {
				return (reClassName).test(this.className);
			}).addClass('js-column-layout');
		}	
	}
});

/*
 * Extend using datepicker from jQuery-UI
 * and set default configuration
 */
HttpCom.extensions.initializeDatepickers = function (scope) {
	$('input.datepicker', scope).attr('readonly', 'readonly')
	.bind('keydown', function (ev) {
		// backspace, delete and Safari delete
		if (ev.keyCode === 8 || ev.keyCode === 46 || ev.keyCode === 63272) {
			this.value = '';
			$(this).trigger('change');
		}
	})
	.datepicker();
}
$(function() {
	$.datepicker.setDefaults({
		// options
		numberOfMonths:2,
		minDate: 0,
		showButtonPanel: true,
		buttonText: ' ',
		showOn: 'both',
		dateFormat: 'dd/mm/yy'
	});
});

/*
 * Extend using fancybox
 */
HttpCom.extensions.initializeFancybox = function (scope) {
	$('a.fancybox', scope).fancybox({
		padding: 0,
		onComplete: function () {
			HttpCom.extend('#fancybox-content');
		}
	});
}

/*
 * Gallery tag filtering
 */
HttpCom.extensions.galleryTags = function (scope) {
	$('ul.gallery-tags a', scope).click(function () {
		var $a = $(this),
			$li = $a.closest('.gallery').find('ul.gallery-items').children(),
			sHref = this.href.substring(this.href.indexOf('#')+1);
		if (sHref && sHref.length) {
			$li.hide().filter('.' + sHref).show();
		}
		else {
			$li.show();
		}
		return false;
	});
}


/* home page height tweaking */
HttpCom.extensions.heightEqualizer = function (scope) {
	var aQuery = ['#home .c6 .box', '#highlights .wrap-inner .box'];
	$.each(aQuery, function (index, sQuery) {
		var $el = $(sQuery, scope),
			nMaxH = 0;
		$el.each(function () {
			nMaxH = Math.max($(this).height(), nMaxH);
		});
		$el.css({
			minHeight:[nMaxH, 'px'].join('')
		})
	});
}
HttpCom.extensions.buttonEqualizer = function (scope) {
	var aQuery = ['#footer-nav .button'];
	$.each(aQuery, function (index, sQuery) {
		var $el = $(sQuery, scope),
			nMaxH = 0;
		// find out max height
		$el.each(function () {
			var $t = $(this), nHeight;
			if ($t.is('button')) {
				nHeight = $t.height();
			}
			else {
				nHeight = parseInt($t.css('paddingTop'), 10) + $t.height() + parseInt($t.css('paddingBottom'), 10)
			}
			nMaxH = Math.max(nHeight, nMaxH);
		});
		//apply max height as min height or padding
		$el.filter('button').css({
			minHeight:[nMaxH, 'px'].join('')
		});
		$el.not('button').each(function () {
			var $t = $(this), nPad;
			sPad = [(nMaxH - $t.height()) / 2, 'px'].join('');
			$t.css({
				paddingTop:sPad,
				paddingBottom:sPad
			});
		});
	});
}
/* check tooltips not going out of the viewport */
HttpCom.extensions.repositionTooltips = function (scope) {
	$('.tooltip-container', scope).bind('mouseover', function () {
		var $t = $(this);
		var $child = $t.children('.tooltip-content'),
			nBodyWidth = $('body').width(),
			nRightBorder = $child.offset().left + $child.width() +
				parseFloat($child.css('padding-left')) || 0 +
				parseFloat($child.css('padding-right')) || 0 +
				parseFloat($child.css('border-left')) || 0 +
				parseFloat($child.css('border-right')) || 0;
		$child.css('marginLeft', Math.min(nBodyWidth - nRightBorder - 20, 0) + 'px');
		
	});
}

/**
 * Displays or attaches an element to show global errors
 * @param {String} text The text to be shown in the error
 * @param {Object} type Optional. If exists, the class of the container will be set to this one
 */
window.showGlobalError = function (text, type) {
	var $div = $('#global-error-slider'),
		sClass = type || 'default';
	if ($div.length) {
		$div.attr('className', sClass).find('span.text').html(text);
	}
	else {
		$div = $('<div id="global-error-slider" class="' + sClass + '" style="display:none"></div>');
		$div.append('<span class="text">' + text + '</span>');
		$div.append('<a class="close" onclick="jQuery(this).parent().remove()">x</a>');
		$('body').prepend($div);
	}
	if ($div.is(':visible')) {
		$div.fadeOut().fadeIn().fadeOut().fadeIn();
	}
	else {
		$div.slideDown();
	}
}

