/* $Id: Common.js,v 1.30 2010/03/08 16:42:45 str Exp $ */

if (typeof Effect != 'undefined')
{
	Effect.DefaultOptions.transition = function(pos)
	{
		if ((pos /= 0.5) < 1) return 0.5 * Math.pow(pos, 4);
		return -0.5 * ((pos -= 2) * Math.pow(pos, 3) - 2);
	};

	Effect.ElementScrollToVert = function(element, container)
	{
		var eo = $(element).cumulativeOffset();
		var co = $(container).cumulativeOffset();
		var options = arguments[2] || {},
		scrollOffsets = Element._returnOffset($(container).scrollLeft, $(container).scrollTop),
		elementOffsets = Element._returnOffset(eo.left - co.left, eo.top - co.top),
		max = $(container).scrollHeight - $(container).getHeight();

		if (options.offset) elementOffsets[1] += options.offset;

		return new Effect.Tween(
			null,
			scrollOffsets.top,
			elementOffsets[1] > max ? max : elementOffsets[1],
			options,
			function(p)
			{
				container.scrollLeft = scrollOffsets.left;
				container.scrollTop = p.round();
			}
		);
	};

	Effect.ElementScrollToHorz = function(element, container)
	{
		var eo = $(element).cumulativeOffset();
		var co = $(container).cumulativeOffset();
		var options = arguments[2] || {},
		scrollOffsets = Element._returnOffset($(container).scrollLeft, $(container).scrollTop),
		elementOffsets = Element._returnOffset(eo.left - co.left, eo.top - co.top),
		max = $(container).scrollWidth - $(container).getWidth();

		if (options.offset) elementOffsets[0] += options.offset;

		return new Effect.Tween(
			null,
			scrollOffsets.left,
			elementOffsets[0] > max ? max : elementOffsets[0],
			options,
			function(p)
			{
				container.scrollLeft = p.round();
				container.scrollTop = scrollOffsets.top;
			}
		);
	};

	Effect.ElementScrollTo = Effect.ElementScrollToVert;

	Effect.ElementScrollToEx = function(element, container)
	{
		var eo = $(element).cumulativeOffset();
		var co = $(container).cumulativeOffset();
		var dims = $(container).getDimensions();
		var options = arguments[2] || {},
		scrollOffsets = Element._returnOffset($(container).scrollLeft, $(container).scrollTop),
		elementOffsets = Element._returnOffset(eo.left - co.left, eo.top - co.top),
		maxScrollWidth = $(container).scrollWidth - dims.width,
        maxScrollHeight = $(container).scrollHeight - dims.height;

		if (options.offsetWidth) elementOffsets[0] += options.offsetWidth;
		if (options.offsetHeight) elementOffsets[1] += options.offsetHeight;

		var w = { start: scrollOffsets.left, range: (elementOffsets[0] > maxScrollWidth ? maxScrollWidth : elementOffsets[0]) - scrollOffsets.left };
		var h = { start: scrollOffsets.top, range: (elementOffsets[1] > maxScrollHeight ? maxScrollHeight : elementOffsets[1]) - scrollOffsets.top };

		return new Effect.Tween(
			null,
			0,
			1,
			options,
			function(p)
			{
				container.scrollLeft = Math.round(w.start + w.range * p);
				container.scrollTop = Math.round(h.start + h.range * p);
			}
		);
	};

	Effect.FadeAndRemove = function(element)
	{
		element = $(element);
		var oldOpacity = element.getInlineOpacity();
		var options = Object.extend({
			from: element.getOpacity() || 1.0,
			to: 0.0,
			duration: 0.5,
			afterFinishInternal: function(effect)
			{
				if (effect.options.to != 0) return;
				effect.element.hide().setStyle({ opacity: oldOpacity });
			},
			afterFinish: function(effect)
			{
				if (element.parentNode != null)
					effect.element.remove();
			}
		}, arguments[1] || {});
		return new Effect.Opacity(element, options);
	};
}

var FastInit = {
    onload: function()
    {
        if (FastInit.done) { return; }
        FastInit.done = true;
        var list = FastInit.f;
        var len = list.length;
        list.sort(FastInit.compare);
        for (var x = 0; x < len; x++)
        {
            list[x].m();
        }
    },
    compare: function(x, y)
    {
        var res = x.prio - y.prio;
        if (res == 0)
            res = x.seq - y.seq;
        return res;
    },
    addOnLoad: function()
    {
        var a = arguments;
        var p = 0;
        for (var x = 0, al = a.length; x < al; x++)
        {
            var arg = a[x];
            if (typeof arg === 'function')
            {
                if (FastInit.done)
                {
                    arg();
                }
                else
                {
                    var l = FastInit.f.length;
                    FastInit.f[l] = { prio: p, seq: l, m: arg };
                }
            }
            else if (typeof arg === 'number')
            {
                p = arg;
            }
        }
    },
    listen: function()
    {
        if (/WebKit|khtml/i.test(navigator.userAgent))
        {
            FastInit.timer = setInterval(function()
            {
                if (/loaded|complete/.test(document.readyState))
                {
                    clearInterval(FastInit.timer);
                    delete FastInit.timer;
                    FastInit.onload();
                }
            }, 10);
        }
        else if (document.addEventListener)
        {
            document.addEventListener('DOMContentLoaded', FastInit.onload, false);
        }
        else if (!FastInit.iew32)
        {
            if (window.addEventListener)
            {
                window.addEventListener('load', FastInit.onload, false);
            }
            else if (window.attachEvent)
            {
                return window.attachEvent('onload', FastInit.onload);
            }
        }
    },
    f: [], done: false, timer: null, iew32: false
};
/*@cc_on@*/
/*@if (@_win32)
FastInit.iew32 = true;
document.write('<script id="__ie_onload" defer src="' + ((location.protocol == 'https:') ? '//0' : 'javascript:void(0)') + '"><\/script>');
document.getElementById('__ie_onload').onreadystatechange = function() { if (this.readyState == 'complete') { FastInit.onload(); } };
/*@end@*/
FastInit.listen();

function contentPartReadMoreLess(l,c)
{
	if(!c.visible())
	{
		c.show();
		l.innerHTML=Language['CityGuide_CityInfo_ReadLess'];
	}
	else
	{
		l.innerHTML=Language['CityGuide_CityInfo_ReadMore'];
		new Effect.SlideUp(c);
		new Effect.ScrollTo(c.previous().identify());
	}
}

var _scripts = new Hash();

function addScriptToDOM(src, afterAddFunc)
{
	var addScript = function()
	{
		var head = $$('head')[0];
		var script = new Element('script');
		script.type = 'text/javascript';
		script.src = src;
		head.appendChild(script);
		if (typeof afterAddFunc == 'function')
			afterAddFunc.defer();
	}
	if (typeof _scripts.get(src) == 'undefined')
	{
		_scripts.set(src, true);
		var found = false;
		$$('script').each(function(e)
		{
			if (e.src == src)
			{
				found = true;
				throw $break;
			}
		});
		if (!found)
			addScript.defer();
	}
}

if (typeof Element != 'undefined')
{
    Element.scrollToElement = function(container, element)
    {
        var c = $(container);
        var co = c.cumulativeOffset()
        var eo = $(element).cumulativeOffset();

        c.scrollLeft = eo.left - co.left;
        c.scrollTop = eo.top - co.top;
    }
}

function waitUntilDefined(variableName, whenDefinedFunc)
{
    var ids = variableName;
    if(typeof variableName == 'string')
        ids = [variableName];
	function _wait()
	{
	    var defined = true;
	    var len = ids.length;
	    for(var i=0;i<len;i++)
	        if(typeof window[ids[i]] == 'undefined')
	        {
	            defined = false;
	            break;
	        }
		if (!defined)
			_wait.delay(0.1);
		else
			whenDefinedFunc();
	}
	_wait.delay(0.1);
}

function waitUntil(queryFunc, whenTrueFunc)
{
	function _wait()
	{
		if (!(queryFunc()))
			_wait.delay(0.1);
		else
			whenTrueFunc();
	}
	_wait.delay(0.1);
}

function getRelativeDate(date)
{
	return date.momondoGetRelativeDate();
}

Object.extend(Date.prototype,
{
	equals: function(d)
	{
		return this.getFullYear() == d.getFullYear() && this.getMonth() == d.getMonth() && this.getDate() == d.getDate();
	},

	daysInMonth: function()
	{
		return Date.daysInMonth(this.getMonth(), this.getFullYear());
	},

	dayOfWeek: function(firstDayOfWeek)
	{
		if (typeof firstDayOfWeek == 'undefined')
			firstDayOfWeek = 1;

		return (this.getDay() - firstDayOfWeek + 7) % 7;
	},

	toUTC: function()
	{
		var d = new Date();
		d.setUTCFullYear(this.getFullYear(), this.getMonth(), this.getDate());
		d.setUTCHours(this.getHours(), this.getMinutes(), this.getSeconds(), this.getMilliseconds());
		return d;
	},

	toUTCDate: function()
	{
		var d = new Date();
		d.setUTCFullYear(this.getFullYear(), this.getMonth(), this.getDate());
		d.setUTCHours(0, 0, 0, 0);
		return d;
	},

	getDateOnly: function()
	{
		return new Date(this.getFullYear(), this.getMonth(), this.getDate());
	},

	dateOnly: function()
	{
		this.setHours(0, 0, 0, 0);
	},

	momondoFormat: function(parameter)
	{
		dy = this.getFullYear();
		dm = this.getMonth() + 1;
		dd = this.getDate();
		ys = dy.toString();
		ms = dm.toString();
		ds = dd.toString();
		if (ms.length == 1) ms = '0' + ms;
		if (ds.length == 1) ds = '0' + ds;
		if (!parameter && currentCulture == 'en-US')
			return ms + '/' + ds + '/' + ys;
		return ds + '-' + ms + '-' + ys;
	},

	momondoGetRelativeDate: function(updateTags)
	{
		if (!updateTags)
			updateTags = true;

		var dateDiff = new Date(new Date() - this).getTime();

		var seconds = Math.floor(dateDiff / 1000) % 60;
		var minutes = Math.floor(dateDiff / (1000 * 60)) % 60;
		var hours = Math.floor(dateDiff / (1000 * 60 * 60)) % 24;
		var days = Math.floor(dateDiff / (1000 * 60 * 60 * 24));
		var result = '';
		if (updateTags)
			result += '<span class="relative_dates_update" time="' + this.getTime() + '">';
		if (days > 1)
		{
			result += String.format(Language['RelativeDate_DaysAgo'], days);
		}
		else if (days == 1)
		{
			result += Language['RelativeDate_DayAgo'];
		}
		else if (hours > 1)
		{
			result += String.format(Language['RelativeDate_HoursAgo'], hours);
		}
		else if (hours == 1)
		{
			result += Language['RelativeDate_HourAgo'];
		}
		else if (minutes > 1)
		{
			result += String.format(Language['RelativeDate_MinutesAgo'], minutes);
		}
		else if (minutes == 1)
		{
			result += Language['RelativeDate_MinuteAgo'];
		}
		else
			result += Language['RelativeDate_MomentsAgo'];
		if (updateTags)
			result += '</span>';
		return result;
	},

	toMomondoDate: function()
	{
		return String.pad(this.getDate(), 2) + '-' + String.pad(this.getMonth() + 1, 2) + '-' + String.pad(this.getFullYear(), 4);
	}
});
Object.extend(String,
{
	pad: function(number, length)
	{
		var str = '' + number;
		while (str.length < length)
		{
			str = '0' + str;
		}
		return str;
	} 
});
Object.extend(Date,
{

    momondoParse: function(s)
    {
        var regex = /(\d+)-(\d+)-(\d\d(\d\d)?)/;
        if (currentCulture == 'en-US')
            regex = /(\d+)\/(\d+)\/(\d\d(\d\d)?)/;
        var match = regex.exec(s);
        if (match != null && match.index >= 0)
        {
            var d = match[1];
            var m = match[2];
            var y = match[3];
            if (currentCulture == 'en-US')
            {
                d = match[2];
                m = match[1];
            }
            if (y.length == 2)
                y = '20' + y;
            return new Date(y, parseInt(m, 10) - 1, d);
        }
        else
        {
            regex = /(\d\d\d\d)(\d\d)(\d\d)((\d\d)(\d\d))?/;
            match = regex.exec(s);
            if (match != null && match.index >= 0)
            {
                var y = match[1];
                var m = match[2];
                var d = match[3];
                var dt = new Date(y, parseInt(m, 10) - 1, d);

                var t = match[4];
                if (t)
                {
                    var h = match[5];
                    var mn = match[6];
                    if (!h) h = 0;
                    if (!mn) mn = 0;
                    dt.setHours(h, mn, 0, 0);
                }
                return dt;
            }
        }
        return null;
    },
    
    daysInMonth: function()
    {
        var a = arguments;
        if (a && a.length > 0)
        {
            var m = -1;
            var y = -1;

            if (a.length == 2)
            {
                m = a[0];
                y = a[1];
            }
            else
            {
                var arg = a[0];
                if (typeof arg == 'object' && typeof arg.getFullYear == 'function')
                {
                    m = arg.getMonth();
                    y = arg.getFullYear();
                }
                else if (typeof arg == 'number')
                {
                    m = arg;
                    y = new Date().getFullYear();
                }
            }

            if (y <= 0 || m < 0 || m >= 12)
                return 0;
            else
                return 32 - new Date(y, m, 32).getDate();
        }
        return 0;
    }
});
(function updateRelativeDates()
{
	$$('.relative_dates_update').each(function(e)
	{
		var d = new Date();
		d.setTime(parseInt(e.attributes['time'].value));
		e.innerHTML = d.momondoGetRelativeDate();
	});
	updateRelativeDates.delay(60);
}).delay(60);

Element.addMethods('TEXTAREA',
{
	elastic: function(element, options)
	{
		if (!options)
			options = {};
			
		element = $(element);
		if (typeof options.watermarkText == 'undefined')
			options.watermarkText = '';
		if (typeof options.controlToShowOnFocus == 'undefined')
			options.controlToShowOnFocus = null;
		else
			options.controlToShowOnFocus = $(options.controlToShowOnFocus);
		if (typeof options.onResize == 'undefined')
			options.onResize = Prototype.emptyFunction;
		if (typeof options.minHeight == 'undefined')
			options.minHeight = 0;
		this.options = options;

		var mimics = ['paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft', 'fontSize', 'lineHeight', 'fontFamily', 'width', 'fontWeight', 'textAlign'];

		var marginbottom = parseInt(element.getStyle('lineHeight')) || parseInt(element.getStyle('fontSize'));
		if (options.minHeight > 0 && marginbottom < options.minHeight)
			marginbottom = options.minHeight;
		var minheight = parseInt(element.getStyle('height')) || marginbottom;
		if (options.minHeight > 0 && minheight < options.minHeight)
			minheight = options.minHeight;
		var goalheight = 0;
		var twin = null;

		function update()
		{
			if (!twin)
			{
				twin = new Element('div').setStyle({ 'display': 'none', 'position': 'absolute' });
				$(document.body).appendChild(twin);
				mimics.each(function(e)
				{
					var style = new Object();
					eval('style.' + e + '=\'' + element.getStyle(e) + '\';');
					twin.setStyle(style);
				});
			}

			var content = element.value.replace(/<|>/g, ' ').replace(/\n/g, '<br />').replace(/&/g, "&amp;").replace(/  /g, ' &nbsp;');
			if (element.value == options.watermarkText)
			{
				element.setStyle({ 'height': marginbottom + 'px' });
				twin.innerHTML = content;
			}
			else if (twin.innerHTML != content)
			{
				twin.innerHTML = content;
				goalheight = (twin.getHeight() + marginbottom > minheight) ? twin.getHeight() + marginbottom : minheight;
				if (Math.abs(goalheight - element.getHeight()) > 1)
					element.setStyle({ 'height': goalheight + 'px' });
				if (options.onResize != null)
					options.onResize();
			}
		}
		element.setStyle({ overflow: 'hidden', display: 'block' });
		element.observe('focus',
			function()
			{
				element.periodicalUpdater = window.setInterval(function() { update(); }, 400);
				if (element.value == options.watermarkText)
				{
					element.addClassName('selected');
					element.removeClassName('unselected');
					element.value = '';
					update();
					if (options.controlToShowOnFocus != null)
						options.controlToShowOnFocus.show();
				}
			}
		);
		element.observe('blur',
			function()
			{
				clearInterval(element.periodicalUpdater);
				this.clearelastic(element);
				update();
			}
		);
		element.value = options.watermarkText;
		element.addClassName('unselected');
		update();
	},
	clearelastic: function(element)
	{
		if (element.value == '')
		{
			element.addClassName('unselected');
			element.removeClassName('selected');
			element.value = options.watermarkText;
			if (this.options.controlToShowOnFocus != null)
				this.options.controlToShowOnFocus.hide();
		}
	},
	unelastic: function(element)
	{
		element = $(element);
		element.stopObserving('focus');
		element.stopObserving('blur');
	}
});

if (typeof Prototype == 'object')
{
	Prototype.Browser.IEMajorVersion = -1;
	var regex = /MSIE (\d+)\.(\d+).*/;
	if (regex.match(navigator.appVersion))
	{
		var matches = regex.exec(navigator.appVersion);
		Prototype.Browser.IEMajorVersion = parseInt(matches[1], 10);
	}
}

if (!String.prototype.parseUrl)
{
	String.prototype.parseUrl = function()
	{
		var matches = this.match(arguments.callee.re);

		if (!matches)
		{
			return null;
		}

		var result = {
			'scheme': matches[1] || '',
			'subscheme': matches[2] || '',
			'user': matches[3] || '',
			'pass': matches[4] || '',
			'host': matches[5],
			'port': matches[6] || '',
			'path': matches[7] || '',
			'query': matches[8] || '',
			'fragment': matches[9] || ''
		};

		return result;
	};

	String.prototype.parseUrl.re = /^(?:([a-z]+):(?:([a-z]*):)?\/\/)?(?:([^:@]*)(?::([^:@]*))?@)?((?:[a-z0-9_-]+\.)+[a-z]{2,}|localhost|(?:(?:[01]?\d\d?|2[0-4]\d|25[0-5])\.){3}(?:(?:[01]?\d\d?|2[0-4]\d|25[0-5])))(?::(\d+))?(?:([^:\?\#]+))?(?:\?([^\#]+))?(?:\#([^\s]+))?$/i;
}