/*
	Detects iOS devices such as iPhone, iPod, iPad
*/
function IfIOSDevice() {
	switch (navigator.platform) {
		case 'iPhone':
		case 'iPhone Simulator':
		case 'iPod':
		case 'iPad':
			return navigator.platform;
			break;
		default: 
			return false;
			break;
	}
}

/*
	Detects iOS 4 devices such as iPhone, iPod, iPad
*/
function GetBrowserVersion() {
	var substr1 = navigator.userAgent.split('Version/')[1];
	
	var version;
	
	if (substr1) {
		version = substr1.split('Mobile')[0];
		if (version) {
			version = version.split('.');
		} else {
			return false
		}
	}
	
	return version;
}
function IfIOS4() {
	var version = GetBrowserVersion();

	if (version) {
		if (version[0]) {
			if (parseInt(version[0]) < 5) {
				return true;
			}
		}
		if (version[1]) {
			if (parseInt(version[1]) < 1) {
				return true;
			}
		}
	}
	
	return false;
}


/* 
	Top bar resizer
*/
function TopBarResizer (conf) {	
	$.extend(this, {
		// properties
		conf: {
			selector: '.top',
			cuteClass: 'top-cute',
			minW: 1024
		},
		el: null,
		
		// methods
		init: function() {
			$.extend(this.conf, conf);
			
			var that = this;
			 
			that.el = $(that.conf.selector);
			
			$(window).resize(function() {
				var winW = $(window).width();
				
				if (winW < that.conf.minW) {
					that.cutify();
				} else {
					that.uncutify();
				}
		
				if (IfIOSDevice() == 'iPhone' || IfIOSDevice() == 'iPod' || /iPhone Simulator/i.test(IfIOSDevice())) {
					var zoom = document.documentElement.clientWidth / window.innerWidth;
					
					if (zoom > 0.5) {
						that.cutify();	
					} else {
						that.uncutify();
					}
				}
			});
			
			$(window).resize();
		},
		
		cutify: function() {
			this.el.addClass(this.conf.cuteClass);
		},
		
		uncutify: function() {
			this.el.removeClass(this.conf.cuteClass);
		}	
	});
	
	this.init();
	
	return this;
}


/* Lang switch
  
   Requires: 
   - mWheely.js - translator script to display current language
*/
function LangSwitcher(conf) {
	$.extend(this, {
		// properties
		conf: {
			parentSelector: '.header-lang-switch',
			itemSelector: '.header-lang-switch-item',
			popupSelector: '.header-lang-switch-popup',
			activeItemClass: 'header-lang-switch-active',
			langIdPrefix: 'lang-'
		},
		lang: 'en',
		parent: null,
		items: null,
		activeItem: null,
		popup: null,
		
		init: function() {
			$.extend(this.conf, conf);
			
			var that = this;
			
			that.lang = $.cookie('lang') ? $.cookie('lang') : 'en';
			that.parent = $(that.conf.parentSelector);
			that.items = $(that.conf.itemSelector);
			that.popup = $(that.conf.popupSelector);
			that.activeItem = $('#' + that.conf.langIdPrefix + that.lang);
			
			that.setCurrentLang();
			
			that.activeItem.click(function(e){
				if (that.popup.is(':visible')) {
					that.popup.hide();
				} else {
					that.popup.show();
					e.stopPropagation();
				}
			});
			
			$(document).click(function(e) {
				var target = $(e.target);
				
				if (!target.is(that.conf.popupSelector)) {
					that.popup.hide();
				}
			});
		},
		
		setCurrentLang: function() {
			var that = this;
			
			that.items.appendTo(that.popup);
			that.activeItem.prependTo(that.parent);
			
			that.activeItem.addClass('pseudo').addClass(that.conf.activeItemClass);
			var linkText = that.activeItem.find('a').html();
			that.activeItem.html(linkText);
			that.activeItem.wrapInner('<span />');
		}
	});
	
	this.init();
	
	return this;
}

/* Timeline object is used for animation */
function Timeline (conf) {
	var defConf = {
		method: 'discrete'
	};
	
	$.extend(this, {
		// properties
		conf: defConf,
		
		min: 0,
		max: 0,

		// pairs like (x, f(rel))
		// x - moment of time
		// f(rel) - interpolator, argument rel is a relative value between 0 and 1
		keyFrames: [],
		
		// methods
		addKeyFrames: function(arr) {
			this.keyFrames = arr.sort(function(a, b) {
				if (a[0] > b[0]) return 1;
				if (a[0] < b[0]) return -1;
				return 0;
			});
		},
		
		addEdges: function(min, max) {
			this.min = min;
			this.max = max;
		},
		
		getFrame: function(x) {
			var frames = this.keyFrames;
			
			if (frames.length < 2) return 0;
			
			for (var i = 0; i < frames.length - 1; i++) {
				if (x >= frames[i][0] && x < frames[i + 1][0]) {
					var rel = (x - frames[i][0]) / (frames[i + 1][0] - frames[i][0]);			
					return frames[i][1](rel);
				}
			}
			
			return frames[frames.length - 1][1](0);
		},
		
		init: function() {
			$.extend(this.conf, conf);
			
			this.min = this.conf.min;
			this.max = this.conf.max;
		}	
	});
	
	this.init();
	
	return this;
}

/* Tab switcher */
function TabSwitcher (conf) {	
	$.extend(this, {
		// properties
		conf: {
			parentSelector: '.hasTabSwitcher',
			linkSelector: '.tab-switcher a',
			tabSelector: '.tabs .tab',
			activeClass: 'active'
		},
		
		init: function() {
			$.extend(this.conf, conf);
			
			var that = this;
			 
			$(that.conf.parentSelector).find(that.conf.linkSelector).click(function(){				
				var link = $(this);
				
				if (!link.is('.active')) {
					$(that.conf.parentSelector).find(that.conf.linkSelector).removeClass(that.conf.activeClass);
					link.addClass(that.conf.activeClass);
					
					$(that.conf.parentSelector).find(that.conf.tabSelector).removeClass(that.conf.activeClass);
					
					var href = link.attr('href');
					var searchFor = href.split('#')[1];
					
					$(that.conf.parentSelector).find('.' + searchFor).addClass(that.conf.activeClass);
				}
				
				return false;
			});
		}	
	});
	
	this.init();
	
	return this;
}


/**
 * Создает куки или возвращает значение.
 *
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Задает куки для сессии.
 * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'site.com', secure: true });
 * @desc Создает куки с опциями.
 * @example $.cookie('the_cookie', null);
 * @desc Удаляет куки.
 * @example $.cookie('the_cookie');
 * @desc Возвращает значение куки.
 *
 * @param String name Имя куки.
 * @param String value Значение куки.
 * @param Object options Объект опций куки.
 * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
 *                             If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
 *                             If set to null or omitted, the cookie will be a session cookie and will not be retained
 *                             when the the browser exits.
 * @option String path The value of the path attribute of the cookie (default: path of page that created the cookie).
 * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
 * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
 *                        require a secure protocol (like HTTPS).
 * @return Значение куки или объект jCommon.
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 * @version 1.0
 */
$.cookie = function(name, value, options) {

	if ('undefined' != typeof value) {
		options = options || {};

		if (null === value) {
			value = '';
			options.expires = -1;
		}

		var expires = '';

		if (options.expires && ('number' == typeof options.expires || options.expires.toUTCString)) {
			var date;

			if ('number' == typeof options.expires) {
				date = new Date();
				date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
			} else {
				date = options.expires;
			}

			expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
		}

		// CAUTION: Needed to parenthesize options.path and options.domain
		// in the following expressions, otherwise they evaluate to undefined
		// in the packed version for some reason…
		var path = options.path ? '; path=' + options.path : '';
		var domain = options.domain ? '; domain=' + options.domain : '';
		var secure = options.secure ? '; secure' : '';
		document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');

		return this;
	}

	var cookieValue = null;

	if (document.cookie && '' != document.cookie) {
		var cookies = document.cookie.split(';');

		for (var i = 0; i < cookies.length; i++) {
			var cookie = jQuery.trim(cookies[i]);

			// Does this cookie string begin with the name we want?
			if (cookie.substring(0, name.length + 1) == (name + '=')) {
				cookieValue = decodeURIComponent(cookie.substring(name.length + 1));

				break;
			}
		}
	}

	return cookieValue;
};

/*

QueryData.js

A function to parse data from a query string

Created by Stephen Morley - http://code.stephenmorley.org/ - and released under
the terms of the CC0 1.0 Universal legal code:

http://creativecommons.org/publicdomain/zero/1.0/legalcode

*/

/* Creates an object containing data parsed from the specified query string. The
 * parameters are:
 *
 * queryString        - the query string to parse. The query string may start
 *                      with a question mark, spaces may be encoded either as
 *                      plus signs or the escape sequence '%20', and both
 *                      ampersands and semicolons are permitted as separators.
 *                      This optional parameter defaults to query string from
 *                      the page URL.
 * preserveDuplicates - true if duplicate values should be preserved by storing
 *                      an array of values, and false if duplicates should
 *                      overwrite earler occurrences. This optional parameter
 *                      defaults to false.
 */
function QueryData(queryString, preserveDuplicates){

  // if a query string wasn't specified, use the query string from the URL
  if (queryString == undefined){
    queryString = location.search ? location.search : '';
  }

  // remove the leading question mark from the query string if it is present
  if (queryString.charAt(0) == '?') queryString = queryString.substring(1);

  // check whether the query string is empty
  if (queryString.length > 0){

    // replace plus signs in the query string with spaces
    queryString = queryString.replace(/\+/g, ' ');

    // split the query string around ampersands and semicolons
    var queryComponents = queryString.split(/[&;]/g);

    // loop over the query string components
    for (var index = 0; index < queryComponents.length; index ++){

      // extract this component's key-value pair
      var keyValuePair = queryComponents[index].split('=');
      var key          = decodeURIComponent(keyValuePair[0]);
      var value        = keyValuePair.length > 1
                       ? decodeURIComponent(keyValuePair[1])
                       : '';

      // check whether duplicates should be preserved
      if (preserveDuplicates){

        // create the value array if necessary and store the value
        if (!(key in this)) this[key] = [];
        this[key].push(value);

      }else{

        // store the value
        this[key] = value;

      }

    }

  }

}
