(function(){
	$.fn.spinner = function() {
		var o = this;
		var frame = 0;
		var height = 44.0;
		var t = function() {
			if(frame == 29) {
				frame = 0;
				o.css('background-position', '0 0');
			} else {
				o.css('background-position', '0 -'+((frame*height)|0).toString()+'px');
			}
			frame += 1;
			setTimeout(t, 1000.0 / 64.0);
		};
		t();
	};
})();

(function(){
	$.fn.center = function() {
		var o = this;

		o.css('margin-left', ($(window).width() - o.width()) * 0.5).
			css('margin-top', ($(window).height() - o.height()) * 0.5);

		$(window).resize(function() {
			var left = ($(window).width() - o.width()) * 0.5;
			var top = ($(window).height() - o.height()) * 0.5;

			left= (left < 0.0) ? 0.0 : left;
			top = (top < 0.0) ? 0.0 : top;

			o.stop().
				animate({marginTop: top, marginLeft: left}, 256.0, 'linear');
		});

		return this;
	}
})();

(function() {
    $.fn.tipsy = function(options) {

        options = $.extend({}, $.fn.tipsy.defaults, options);

        return this.each(function() {

            var opts = $.fn.tipsy.elementOptions(this, options);

            $(this).hover(function() {

                $.data(this, 'cancel.tipsy', true);

                var tip = $.data(this, 'active.tipsy');
                if (!tip) {
                    tip = $('<div class="tipsy"><div class="tipsy-inner"/></div>');
                    tip.css({position: 'absolute', zIndex: 100000});
                    $.data(this, 'active.tipsy', tip);
                }

                if ($(this).attr('title') || typeof($(this).attr('original-title')) != 'string') {
                    $(this).attr('original-title', $(this).attr('title') || '').removeAttr('title');
                }

                var title;
                if (typeof opts.title == 'string') {
                    title = $(this).attr(opts.title == 'title' ? 'original-title' : opts.title);
                } else if (typeof opts.title == 'function') {
                    title = opts.title.call(this);
                }

                tip.find('.tipsy-inner')[opts.html ? 'html' : 'text'](title || opts.fallback);

                var pos = $.extend({}, $(this).offset(), {width: this.offsetWidth, height: this.offsetHeight});
                tip.get(0).className = 'tipsy'; // reset classname in case of dynamic gravity
                tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).appendTo(document.body);
                var actualWidth = tip[0].offsetWidth, actualHeight = tip[0].offsetHeight;
                var gravity = (typeof opts.gravity == 'function') ? opts.gravity.call(this) : opts.gravity;

                switch (gravity.charAt(0)) {
                    case 'n':
                        tip.css({top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}).addClass('tipsy-north');
                        break;
                    case 's':
                        tip.css({top: pos.top - actualHeight - 16.0, left: pos.left + pos.width / 2 - actualWidth / 2}).addClass('tipsy-south');
                        break;
                    case 'e':
                        tip.css({top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}).addClass('tipsy-east');
                        break;
                    case 'w':
                        tip.css({top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}).addClass('tipsy-west');
                        break;
                }

                if (opts.fade) {
                    tip.css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: 0.8});
                } else {
                    tip.css({visibility: 'visible'});
                }

            }, function() {
                $.data(this, 'cancel.tipsy', false);
                var self = this;
                setTimeout(function() {
                    if ($.data(this, 'cancel.tipsy')) return;
                    var tip = $.data(self, 'active.tipsy');
                    if (opts.fade) {
                        tip.stop().fadeOut(function() { $(this).remove(); });
                    } else {
                        tip.remove();
                    }
                }, 1);

            });

        });

    };

    // Overwrite this method to provide options on a per-element basis.
    // For example, you could store the gravity in a 'tipsy-gravity' attribute:
    // return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' });
    // (remember - do not modify 'options' in place!)
    $.fn.tipsy.elementOptions = function(ele, options) {
        return $.metadata ? $.extend({}, options, $(ele).metadata()) : options;
    };

    $.fn.tipsy.defaults = {
        fade: false,
        fallback: '',
        gravity: 'n',
        html: false,
        title: 'title'
    };

    $.fn.tipsy.autoNS = function() {
        return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n';
    };

    $.fn.tipsy.autoWE = function() {
        return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w';
    };

})();

(function(){
	$.fn.fullscreen = function() {
		var o = this;
		o.css('margin-left', 0.0).css('margin-top', 0.0);
		$(window).resize(function() {
			o.width($(window).width()).
				height($(window).height());
		}).scroll(function() {
			if(!isNaN(window.scrollY)) {
				o.css('top', window.scrollY);
			}
		});
		return this;
	}
})();

function fixstupidmousewheelonmacwhereelse(id) {
	if(navigator.appVersion.toLowerCase().indexOf("mac") == -1) {
		return;
	}
	
	var o = $('#'+id).get(0);
	var wheely = function(event) {
		var delta = 0.0;

		if (event.wheelDelta) {
			delta = event.wheelDelta / 120.0;
			if (window.opera) {
				delta = -delta;
			}
		} else {
			if (event.detail) {
				delta = -event.detail;
			}
		}

		if (delta) {
			o.externalMouseEvent(delta);
		}

		if (event.preventDefault) {
			event.preventDefault();
		}

		event.returnValue = false;
	};

	if (window.addEventListener) {
		window.addEventListener('DOMMouseScroll', wheely, false);
	}

	window.onmousewheel = document.onmousewheel = wheely;
}

(function(){
	if(window.cular) { return; }
	var cular = window.cular = { appWindow: null };
	var isWindows = navigator.userAgent.indexOf('Windows') != -1;

	cular.init = function() {
		$('textarea').keypress(function(event) {
			if(event.ctrlKey && (event.which == 13 || event.which == 10)) {
				$(this).closest('form').submit();
			}
		});

		$('a[rel="audiotool"]').bind('click', function(e){
			e.preventDefault();
			cular.launch(this);
			return false;
		});

		var timeout= -1;
		$('#menu').
			bind('mouseover', function(){
				if(-1 != timeout) { clearInterval(timeout); timeout = -1; }
				$(this).find('ul').css('visibility', 'visible');
			}).
			bind('mouseout', function(){
				var o = this;
				timeout = setTimeout(function() {$(o).find('ul').css('visibility', 'hidden'); timeout = -1;}, 128.0);
			});

		$('a[rel="cover"]').fancybox({'padding': 0, 'titleShow': false, 'overlayColor': '#000000', 'overlayOpacity': 0.5});
		$('a[rel="avatar"]').fancybox({'type': 'image', 'padding': 0, 'titleShow': false, 'overlayColor': '#000000', 'overlayOpacity': 0.5});
		$('a[rel="dialog"]').fancybox({'padding': 0, 'titleShow': false, 'overlayColor': '#000000', 'overlayOpacity': 0.5});
		$('.with-tooltip').tipsy({gravity:'s'});
		try { $('#ajax-fullscreen').fullscreen(); } catch(e) {}
		try { $('#ajax-loader').spinner(); } catch(e) {}
		try { $('#ajax-container').center(); } catch(e) {}
		cular.playlist.init();
	};

	cular.notice = function(id) {
		var o = $('#'+id);
		if(o.children().length > 0) {
			o.show();
			setTimeout(function(){$('#ajax-fullscreen').show().fadeIn(256.0)},8);
			setTimeout(function(){$('#ajax-fullscreen').fadeOut(512.0)}, 1500.0);
		}
	};
	
	cular.launch = function(element) {
		var href = element ? element.href : '/app';
		if (null == cular.appWindow || (null != cular.appWindow && cular.appWindow.closed)) {
			var multiplier = 1.0;//(navigator.userAgent.indexOf('Chrome') != -1 && navigator.userAgent.indexOf('Linux') != -1) ? 0.5 : 1.0;
			var actualScreenWidth = screen.width * multiplier;
			var actualScreenHeight = screen.height;
			var width = Math.floor(actualScreenWidth * 0.75);
			var height = Math.floor(actualScreenHeight * 0.75);
			var left = Math.floor((actualScreenWidth - width) * 0.5);
			var top = Math.floor((actualScreenHeight - height) * 0.5);
			cular.appWindow = window.open(href, 'app', 'location=no,status=no,menubar=no,toolbar=no,resizable=yes,scrollbars=no,width='+width+',height='+height+',left='+left+',top='+top);
		} else {
			cular.appWindow.location.href = href;
		}
		if (null != cular.appWindow) {
			cular.appWindow.focus();
		}
		return false;
	};

	cular.playlist = {
		items: [],
		map: [],
		title: '',
		current: null,

		init: function() {
			var playlist = cular.playlist;
			playlist.title = top.document.title;
		},

		onPlay: function(playlistObject) {
			var playlist = cular.playlist;

			if(typeof playlistObject == 'string') {
				playlistObject = playlist.map[playlistObject];
			}

			if(null != playlist.current && playlist.current != playlistObject) {
				playlist.current.onStop();
			}

			if(!isWindows) {
				top.document.title = '\u25b6 '+playlist.title;
			}
			
			playlist.current = playlistObject;
		},

		onPause: function() {
			var playlist = cular.playlist

			top.document.title = playlist.title
		},

		onComplete: function() {
			var playlist = cular.playlist

			top.document.title = playlist.title
			
			if(null != playlist.current) {
				var index = playlist.items.indexOf(playlist.current)+1
				var last = playlist.current.publicKey

				playlist.current = null;

				if(0 != index) {//0 since +1
					while(index < playlist.items.length) {
						var next = playlist.items[index]

						if(next.publicKey != last) {
							try {
								playlist.items[index].onPlay()
							} catch(e) { /* swallow! */ }
							break
						}
						
						index += 1
					}
				}
			}
		},

		append: function(items) {
			var playlist = cular.playlist;

			if(typeof items == 'string') {
				var playlistObject = {
					publicKey: arguments[1],
					onPlay: function() { $('#'+items).get(0).play(); },
					onStop: function() { $('#'+items).get(0).stop(); }
				};
				playlist.map[items] = playlistObject;
				playlist.items.push(playlistObject);
			} else if(items instanceof Array) {
				playlist.items = playlist.items.concat(items);
			} else {
				playlist.items.push(items);
			}
		}
	};

	cular.onBeforeUnload = function(e) {
		var event = e || window.event;
		var message = 'Are you sure you want to exit? All unsaved changes will be lost.';
		if (event) { event.returnValue = message; }
		return message;
	};

	//
	// ExternalInterface
	//
	
	cular.trapExit = function(value) { window.onbeforeunload = value ? cular.onBeforeUnload : null; };
	cular.onDocumentTitle = function(title) { try { top.document.title = title + ' - Audiotool'; } catch(e) {} };
	cular.initAddon = function() {
		if(!navigator.javaEnabled()) {
			window.alert('Awww!\n\nJava is required for all the fancy stuff.\nGrab it at ' +
				'http://java.com/download and come back.');
			return false;
		}

		var applet = document.createElement('applet');
		applet.setAttribute('width', '1');
		applet.setAttribute('height', '1');
		applet.setAttribute('name', 'Audiotool Addon');
		applet.setAttribute('code', 'de.despudelskern.proaddon.server.BrowserSupport');
		applet.setAttribute('archive', 'http://audiotool.s3.amazonaws.com/jar/addon.jar');
		applet.setAttribute('mayscript', 'mayscript');

		var parameters = [
			{name: 'separate_jvm', value: 'true'},
			{name: 'boxborder', value: 'false'},
			{name: 'noddraw.check', value: 'true'},
			{name: 'progressbar', value: 'false'}
		];

		for(var p in parameters) {
			var param = document.createElement('param');
			param.setAttribute('name', p.name);
			param.setAttribute('value', p.value);
			applet.appendChild(param);
		}

		$('#app-addon').append(applet);
		return true;
	};

	function onAddonInitialized(value) { try { $('#audiotool').onAddonInitialized(value); } catch(e) {} }
})();
