var Player = Base.extend({

	constructor: function(theUserId, theWebsiteId, theCachedWebsiteId) {
		this.DEBUG_MUTE_MIDI_FLAG = 0;
		this.MAX_LOADING_TIME = 10000;
		this.myUserId = theUserId;
		this.myWebsiteId = theWebsiteId;
		this.myCachedWebsiteId = theCachedWebsiteId;
		this.injectBehaviour();
		this.addCandy();
		this.myFlying = 1;
		this.myStarsX = 0;
		this.myLoadingTimeout = null;
		this.myMidiLengthTimer = null;
		this.myIdCounter = 0;
		this.myFirstPlay = 1;
		this.myWebsiteLoaded = 0;
		this.myCachedWebsiteLoaded = 0;
		this.startup();
	},
	
	injectBehaviour : function() {
		var me = this;
		var myNextLink = $("#next_link");
		myNextLink.removeAttr('href');
		this.activateNextLink();
		$("#midi_controls form input").remove();
		$("#midi_controls form").append('<input id="stop_link" type="button" value="STOP" />');
		var myTitleLink = $("#midi_titles h2 marquee a");
		var myTitleMarquee = $("#midi_titles h2 marquee");
		var myTitle =  $("#midi_titles h2");
		myTitleMarquee.remove();
		var myMarqueeDiv = document.createElement("div");
		$(myMarqueeDiv).attr("class", "marquee");
		$(myTitle).append(myMarqueeDiv);	
		$(myMarqueeDiv).append(myTitleLink);
		myTitleLink.click(function() { me.pause(); });
	},
	
	addCandy : function() {
		var myFire = document.createElement("img");
		$(myFire).attr("src","layout/images/fire.gif");
		$(myFire).attr("id","fire");
		$("#midi_titles").append(myFire);
		var myNextCaption = document.createElement("span");
		$(myNextCaption).text("NEXT");
		$(myNextCaption).attr("id","next_caption");
		$("#midi_controls").append(myNextCaption);
	},
	
	startup : function() {
		this.checkHash();
		this.myWebsite = new Website(this.nextId(), this.myWebsiteId, this, this.onWebsiteLoaded);
		this.myCachedWebsite = new Website(this.nextId(), this.myCachedWebsiteId, this, this.onCachedWebsiteLoaded);
		this.whileLoading();
		this.animateStars();
	},
	
	checkHash : function() {
		var myHash = location.hash;
		if (myHash != "") {
			myHash = myHash.substr(1, myHash.length-1);
			this.myWebsiteId = myHash;
		}
	},
	
	setHash : function() {
		location.hash = this.myWebsiteId;
	},
	
	onWebsiteLoaded : function() {
		this.myWebsiteLoaded = 1;
		if (this.myCachedWebsiteLoaded) {
			this.playNext();
		}
	},
	
	onCachedWebsiteLoaded : function() {
		this.myCachedWebsiteLoaded = 1;
		if (this.myWebsiteLoaded) {
			this.playNext();
		}
	},
	
	whileLoading : function() {
		var me = this;
		clearTimeout(this.myLoadingTimeOut);
		this.myLoadingTimeout = setTimeout(function() { me.forcedNext(); }, this.MAX_LOADING_TIME);
		this.blockNextLink();
		this.blockStopLink();
		$("#url").attr("value", "loading...");
	},
	
	playNext : function() {
		clearTimeout(this.myLoadingTimeout);
		this.activateNextLink();
		this.activateStopLink();
		this.myWebsiteId = this.myWebsite.id();
		this.setHash();
		if (this.myFirstPlay) {
			this.myFirstPlay = 0;
			this.myWebsite.play();
		}
	},
	
	next : function() {
		this.whileLoading();
		this.myWebsite.stop();
		this.myWebsite = this.myCachedWebsite;
		this.myWebsite.play();
		this.myCachedWebsite = new Website(this.nextId(), -1, this, this.onCachedWebsiteLoaded);
		this.swapNextLink();
	},
	
	forcedNext : function() {
		if (!this.myWebsite.isPlaying()) {
			this.myWebsite = new Website(this.nextId(), -1, this, this.onWebsiteLoaded);
		} else {
		}
		//this.myCachedWebsite.stop();
		this.myCachedWebsite = new Website(this.nextId(), -1, this, this.onCachedWebsiteLoaded);
		//this.whileLoading();
	},
	
	activateNextLink : function() {
		var me = this;
		var myNextLink = $("#next_link");
		myNextLink.removeAttr("class");
		myNextLink.click(function() {me.next();});
		$("#next_caption").removeAttr("class");
	},
	
	blockNextLink : function() {
		var myNextLink = $("#next_link");
		myNextLink.attr("class", "disabled");
		myNextLink.unbind();
		$("#next_caption").attr("class", "hidden");
	},
	
	deactivateNextLink : function() {
		this.blockNextLink();
		$("#next_link").attr("class", "hidden");
	},
	
	swapNextLink : function() {
		$("#next_link").load("layout/next_link.php");
	},
	
	stop : function() {
		clearTimeout(this.myLoadingTimeout);
		this.endTimer();
		this.myWebsite.stop();
		this.activateStartLink();
		this.deactivateNextLink();
		this.removePlayerInfo();
		$("#fire").attr("class", "hidden");
		this.myFlying = 0;
	},	
	
	activateStopLink : function() {
		var myStopLink = $("#stop_link");
		myStopLink.unbind();
		var me = this; myStopLink.click(function() {me.stop();});
		myStopLink.attr("value", "STOP");	
		myStopLink.removeAttr("class");
	},
	
	blockStopLink : function() {
		$("#stop_link").attr("class", "hidden");
	},
	
	start : function() {
		$("#fire").removeAttr("class");
		this.activateStopLink();
		this.next();
		this.myFlying = 1;
		this.animateStars();
	},
	
	activateStartLink : function() {
		var myStopLink = $("#stop_link");
		myStopLink.unbind();
		myStopLink.attr("value", "START");
		var me = this; myStopLink.click(function() {me.start();});
	},
	
	pause : function() {
		this.stopMidi();
		clearTimeout(this.myLoadingTimeout);
		this.endTimer();
		this.activateStartLink();
		this.deactivateNextLink();
		this.activateResumeLink();
	},
	
	activateResumeLink : function() {
		this.activateStartLink();
		var myStopLink = $("#stop_link");
		myStopLink.attr("value", "RESUME");
		myStopLink.unbind();
		var me = this; myStopLink.click(function() {
			me.myWebsite.resume();
			me.activateNextLink();
			me.activateStopLink();
		});	
	},
	
	playMidi : function(theMidi, theMidiLength) {
		if ($("#player") != undefined) {
			$("#player").remove();
		}
		if (theMidi != "") {
			var myEmbed = document.createElement("embed");
			myEmbed.id = "player";
			myEmbed.src = theMidi;
			myEmbed.width = "0";
			myEmbed.height = "0";
			$(myEmbed).attr("autostart", "true");
			$(myEmbed).attr("loop", "false");
			$(myEmbed).attr("hidden", "true");
			if (this.DEBUG_MUTE_MIDI_FLAG) {
				$(myEmbed).attr("volume", "0");
			}
			$("#interface").append(myEmbed);
			this.startTimer(theMidiLength);
		}
	},
	
	stopMidi : function() {
		$("#player").remove();
	},
	
	startTimer : function(theMilliseconds) {
		var me = this;
		theMilliseconds = parseInt(theMilliseconds) / 10 + 2000;
		clearTimeout(this.myMidiLengthTimer);
		this.myMidiLengthTimer = setTimeout(function() { me.next(); }, theMilliseconds);
	},
	
	endTimer : function() {
		clearTimeout(this.myMidiLengthTimer);
	},
	
	setPlayerInfo : function(theText, theUrl, theMidiUrl) {
		var myUrl = $("#url");
		myUrl.attr("value", theMidiUrl);
		myUrl.attr("size", theMidiUrl.length);
		var myTitle =  $("#midi_titles h2");
		var myTitleLink = $("#midi_titles h2 .marquee a");
		myTitleLink.text(theText);
		myTitleLink.attr('href', theUrl);
		myTitleLink.stop();
		var myMaxLeft = myTitle.width();
		var myMinLeft = -1 * myTitleLink.width();
		var myMarquee = new Marquee(myTitleLink, theText.length * 500, myMinLeft, myMaxLeft, "linear", this, null);	
	},
	
	removePlayerInfo : function() {
		$("#url").attr("value", "");
		$("#midi_titles h2 .marquee a").text('');
	},
	
	nextId : function() {
		var myId = this.myIdCounter;
		this.myIdCounter++;
		return myId;
	},
	
	userId : function() {
		return this.myUserId;
	},
	
	
	
	animateStars : function() {
		this.myStarsX -= 1;
		$("body").css({"background-position": this.myStarsX + "px 0px"});
		var me = this;
		var myBgTimeout = setTimeout(function() { if (me.myFlying) { me.animateStars(); } }, 50);
	}
	
});


////////////////////////////////////////////////////////////////////////////////////////
var Website = Base.extend({

	constructor: function(theId, theWebsiteId, theParent, theCallback) {
		this.myId = theId;
		this.myUserId = theParent.userId();
		this.myWebsiteId = theWebsiteId;
		this.myParent = theParent;
		this.myCallback = theCallback;
		this.myIsPlaying = 0;
		this.myWebsiteData = null;
		this.loadWebsite();
		this.myBackground = null;
	},
	
	loadWebsite : function() {
		var me = this;
		$.getJSON("data/load_website.php", {'uid': this.myUserId, 'wid': this.myWebsiteId},
		function(theData){
			me.myWebsiteData = theData;
			me.onWebsiteLoaded();
		});
	},
	
	onWebsiteLoaded : function() {
		this.myWebsiteId = this.myWebsiteData["id"];
		this.loadBackground();
	},
	
	loadBackground : function() {
		var me = this;
		$.getJSON("data/background.php", {'id': this.myWebsiteId},
		function(theData){
			me.myBackground = new Background(me.myId, theData, me);
		});
	},
	
	onBackgroundLoaded : function() {
		this.myCallback.apply(this.myParent, arguments);
	},
	
	play : function() {
		this.myParent.setPlayerInfo(this.myWebsiteData["page_title"], this.myWebsiteData["url"], this.myWebsiteData["midi_url"]);
		this.myParent.playMidi(this.myWebsiteData["midi_url"], this.myWebsiteData["midi_length"]);	
		this.myBackground.start();
		this.myIsPlaying = 1;
	},
	
	resume : function() {
		this.myParent.playMidi(this.myWebsiteData["midi_url"], this.myWebsiteData["midi_length"]);
		this.myIsPlaying = 1;
	},
	
	stop : function() {
		this.myParent.stopMidi();
		this.myBackground.stop();
		this.myIsPlaying = 0;
	},
	
	id : function() {
		return this.myWebsiteId;
	},
	
	isPlaying : function() {
		return this.myIsPlaying;
	}
	
});


////////////////////////////////////////////////////////////////////////////////////////
var Background = Base.extend({

	constructor: function(theId, theImagesInfo, theParent) {
		this.SCREEN_EXPAND = 50;
		this.IMAGE_MAX_SIZE = 120;
  		this.myId = theId;
  		this.myImagesInfo = theImagesInfo;
  		this.myParent = theParent;
  		this.myNumberOfImagesToLoad = 0;
  		this.myWidth = 0;
  		this.myStopFlag = 0;
  		this.myMarquees = new Array();
  		this.createContainer();
  		this.insertImages();
	},
	
	createContainer : function() {
		var myContainer = document.createElement("div");
		$(myContainer).attr({
			'id': 'background' + this.myId,
			'class': 'background',
			'style': 'display:none'
		});
		$(myContainer).insertBefore($("h1"));
	},
  
	insertImages : function() {
		var myMinWidth = $(window).width();
		var myMaxHeight = $(window).height() + this.SCREEN_EXPAND;
		for(var myGraphicToCount in this.myImagesInfo) {
			this.myNumberOfImagesToLoad += parseInt(this.myImagesInfo[myGraphicToCount].how_often);
		}
		for(var myGraphic in this.myImagesInfo) {
			var myImageWidth = this.myImagesInfo[myGraphic].width;
			var myImageHeight = this.myImagesInfo[myGraphic].height;
			if (myGraphic.substr(myGraphic.lastIndexOf('.') + 1) == "jpg"
			&& myImageWidth > this.IMAGE_MAX_SIZE && myImageHeight > this.IMAGE_MAX_SIZE) {
				myImageWidth = Math.min(this.IMAGE_MAX_SIZE, myImageWidth);
				myImageHeight = Math.min(this.IMAGE_MAX_SIZE, myImageHeight);
			}
			var myHowOften = this.myImagesInfo[myGraphic].how_often;
			for (var n=0; n<myHowOften; n++) {
				var myMarqueeWidth = 2 * myImageWidth + myMinWidth;
				if (myHowOften > 1 && n > 0) {
					myMarqueeWidth += + 1.5 * Math.random() * myMinWidth;
				}
				myMarqueeWidth = Math.round(myMarqueeWidth);
				this.myWidth = Math.max(this.myWidth, myMarqueeWidth);
				myMarqueeX = -1 * myImageWidth;
				myMarqueeY = -0.5 * this.SCREEN_EXPAND + Math.round(Math.random() * (myMaxHeight - myImageHeight));
				var myMarquee = document.createElement("div");
				$(myMarquee).css({
					'top': myMarqueeY + 'px',
					'left': myMarqueeX + 'px',
					'width': myMarqueeWidth + 'px'
				});
				$("#background" + this.myId).append(myMarquee);
				var myImage = document.createElement("img");
				var myImageLeft = parseInt(myMarqueeWidth) + parseInt(myImageWidth);
				$(myImage).attr({
					'src': myGraphic,
					'height': myImageHeight,
					'width': myImageWidth
				});
				$(myImage).css({'left': myImageLeft + 'px'});
				var me = this;
				$(myImage).load(function() {me.onImageLoaded();});
				$(myMarquee).append(myImage);
			}
		}
	},
	
	onImageLoaded : function() {
		this.myNumberOfImagesToLoad--;
		if (this.myNumberOfImagesToLoad == 0) {
			this.myParent.onBackgroundLoaded();
		} 
	},
	
	start : function() {
		var me = this;
		$("#background" + this.myId).css({'display': 'block'});
		jQuery.each($("#background" + this.myId + " img"), function (i, myElement) {
			var myMarquee = new Marquee(myElement, 0, 0, 0, "linear", this, null);
			me.myMarquees.push(myMarquee);
		});
	},
	
	stop : function() {
		var me = this;
		for (var i=0; i<this.myMarquees.length; i++) {
			this.myMarquees[i].stop();
		}
		var myBackground = $("#background" + this.myId);
		var myMarquee = new Marquee(myBackground, 22000, -1 * this.myWidth, 0, "swing", this, me.remove);
	},
	
	remove : function() {
		$("#background" + this.myId).remove();
	}
	
});


////////////////////////////////////////////////////////////////////////////////////////
var Marquee = Base.extend({

	constructor: function(theElement, theSpeed, theMinLeft, theMaxLeft, theEasing, theParent, theCallback) {
		this.MIN_SPEED_DELAY = 14000;
		this.VARIABLE_SPEED_DELAY = 24000;
		this.myElement = theElement;
		this.mySpeed = theSpeed;
		this.myMinLeft = theMinLeft;
		this.myMaxLeft = theMaxLeft;
		this.myEasing = theEasing;
		this.myParent = theParent;
		this.myCallback = theCallback;
		this.myStopFlag = 0;
		this.start();
	},
	
	start : function() {
		var mySpeed = this.mySpeed <=0 ? this.MIN_SPEED_DELAY + Math.random() * this.VARIABLE_SPEED_DELAY : this.mySpeed;
		this.myMaxLeft = this.myMaxLeft <= 0 ? parseInt($(this.myElement).css("left")) : this.myMaxLeft;
		$(this.myElement).css({'left': this.myMaxLeft + 'px'});
		var me = this;
		$(this.myElement).animate(
			{left: this.myMinLeft + "px"},
			mySpeed,
			this.myEasing,
			function() {
				if (me.myCallback == null && !me.myStopFlag) {
					me.start();
				}
				if (me.myCallback != null) {
					me.myCallback.apply(me.myParent, arguments);
				}
			}
		);
	},
	
	stop : function() {
		this.myStopFlag = 1;
	}
	
});
