//
//  HypeAudio.js
//  Hype
//
//  Created by Jonathan Deutsch on 7/17/12.
//  Copyright (c) 2012 Tumult Inc. All rights reserved.
//

var HypeAudio_allAudios = {};
var audioContext = null;

function HypeAudio(audioMethodAPI, oid, sourceURLsByMimeType, options) {
	var hypeAudio = HypeAudio_allAudios[oid];
	if(hypeAudio != null) {
		return hypeAudio;
	}
	
	hypeAudio = new audioMethodAPI(oid, sourceURLsByMimeType);

	hypeAudio.oid = oid;
	hypeAudio.sourceURLsByMimeType = sourceURLsByMimeType;
	hypeAudio.options = options;

//  default values:
//	hypeAudio.playWhenFinishedLoading = false;
//	hypeAudio.isLoading = false;
//	hypeAudio.isLoaded = false;
//	hypeAudio.audioBuffer = null;
//	hypeAudio.loop = false;

	hypeAudio.sortedMimeTypes = (function () {
		var mimeTypes = Array();
		for(var mimeType in hypeAudio.sourceURLsByMimeType) {
			if(hypeAudio.sourceURLsByMimeType.hasOwnProperty(mimeType) == false) {
				continue;
			}
			mimeTypes.push(mimeType);
		}
		return mimeTypes.sort();
	});

	return hypeAudio;
}

function HypeAudio_HTML5(oid, sourceURLsByMimeType) {
	var _hypeAudio = this;
	HypeAudio_allAudios[oid] = _hypeAudio;

	_hypeAudio.setupAudioElement = (function (errorCallback) {
		var audioElement = document.createElement("audio");
		_hypeAudio.audioElement = audioElement;
		var sortedMimeTypes = _hypeAudio.sortedMimeTypes();
		for(var i = 0; i < sortedMimeTypes.length; i++) {
			var mimeType = sortedMimeTypes[i];
			var sourceElement = document.createElement("source");
			var sourceURL = _hypeAudio.sourceURLsByMimeType[mimeType];
			sourceElement.setAttribute("src", sourceURL);
			sourceElement.setAttribute("type", mimeType);
			audioElement.appendChild(sourceElement);
		}
		document.body.appendChild(audioElement);
		
		return audioElement;
	});

	_hypeAudio.load = (function (successCallback, errorCallback) {
		if(_hypeAudio.isLoaded == true || _hypeAudio.isLoading == true) {
			return;
		}
		
		var audioElement = _hypeAudio.setupAudioElement(errorCallback);
		
		var loadCompleteFunction = (function() {
			window.clearTimeout(_hypeAudio.watchdog);
			if(_hypeAudio.isLoaded == true) {
				return;
			}
			
			_hypeAudio.isLoading = false;
			_hypeAudio.isLoaded = true;
			if(successCallback != null) {
				successCallback(_hypeAudio);
			}
			if(_hypeAudio.playWhenFinishedLoading == true) {
				_hypeAudio.play();
			}
		});

		var errorFunction = (function() {
			window.clearTimeout(_hypeAudio.watchdog);
			if(_hypeAudio.isLoaded == true) {
				return;
			}
			_hypeAudio.isLoading = false;
			if(errorCallback != null) {
				errorCallback(_hypeAudio);
			}
		});

		audioElement.addEventListener("canplaythrough", loadCompleteFunction, true);
		audioElement.addEventListener("abort", errorFunction, true);
		audioElement.addEventListener("error", errorFunction, true);
		_hypeAudio.watchdog = window.setTimeout(errorFunction, 15000); // watchdog timer to make sure the document still loads after 15 seconds (ex: ogg preload on ios gives no error)
		
		_hypeAudio.isLoading = true;
		if(navigator.onLine == null || navigator.onLine == true) {
			audioElement.load();
		} else {
			loadCompleteFunction();
		}
	});
	
	_hypeAudio.play = (function () {
		if(_hypeAudio.isLoaded != true) {
			if(_hypeAudio.isLoading == true) {
				_hypeAudio.playWhenFinishedLoading = true;
				return;
			}
			_hypeAudio.isLoaded = true;
		}
		
		if(_hypeAudio.audioElement == null) {
			_hypeAudio.setupAudioElement(null);
		}
				
		try {
			_hypeAudio.audioElement.loop = _hypeAudio.loop;
			_hypeAudio.audioElement.currentTime = 0;
		} catch(e) { }
		_hypeAudio.audioElement.play();
	});

	_hypeAudio.pause = (function () {
		if(_hypeAudio.isLoaded != true) {
			_hypeAudio.playWhenFinishedLoading = false;
			return;
		}

		if(_hypeAudio.audioElement != null) {
			_hypeAudio.audioElement.pause();
		}
	});
}

function HypeAudio_WebAudioAPI(oid, sourceURLsByMimeType) {
	var _hypeAudio = this;
	HypeAudio_allAudios[oid] = _hypeAudio;

	if(audioContext == null) {
		if(typeof AudioContext !== "undefined") {
			audioContext = new AudioContext();
		} else if(typeof webkitAudioContext !== "undefined") {
			audioContext = new webkitAudioContext();
		}
	}

	_hypeAudio.load = (function (successCallback, errorCallback) {
		if(_hypeAudio.isLoaded == true || _hypeAudio.isLoading == true) {
			return;
		}
		
		_hypeAudio.isLoading = true;
		
		var decodeArrayBuffer = (function (arrayBuffer) {
			audioContext['decodeAudioData'](arrayBuffer, (function (audioBuffer) {
				_hypeAudio.audioBuffer = audioBuffer;
				_hypeAudio.isLoading = false;
				_hypeAudio.isLoaded = true;

				if(successCallback != null) {
					successCallback(_hypeAudio);
				}
				if(_hypeAudio.playWhenFinishedLoading == true) {
					if(_hypeAudio.source != null && _hypeAudio.options.startAheadOfPlayback == true) {
						_hypeAudio.source['buffer'] = audioBuffer;
					} else {
						_hypeAudio.play();
					}
				}
			}), (function (audioBuffer) {
				_hypeAudio.isLoading = false;
				if(errorCallback != null) {
					errorCallback(_hypeAudio);
				}			
			}));
		});
	
	
		// use a '?' at the end to trigger the NETWORK: variant of the resource when using the cache manifest
		var url = _hypeAudio.validSourceURL();
		if(url.indexOf("?") == -1) {
			url = "" + url + "?";
		}
		
		var request = new XMLHttpRequest();
		request.open("GET", url, true);
		request.responseType = "arraybuffer";		
		
		request.onload = (function () {
			decodeArrayBuffer(request.response);
		});
		
		request.onerror = (function () {
			_hypeAudio.isLoading = false;
			if(errorCallback != null) {
				errorCallback(_hypeAudio);
			}
		});
		
		request.send();
	});
	
	_hypeAudio.play = (function () {
		_hypeAudio._stop();

		_hypeAudio.source = audioContext['createBufferSource']();
		_hypeAudio.source['connect'](audioContext['destination']);
		_hypeAudio.source['loop'] = _hypeAudio.loop;
		
		if(_hypeAudio.options.startAheadOfPlayback == true) {
			_hypeAudio._start();
		}

		if(_hypeAudio.isLoaded != true) {
			_hypeAudio.playWhenFinishedLoading = true;
			_hypeAudio.load();
			return;
		} else {
			_hypeAudio.source['buffer'] = _hypeAudio.audioBuffer;
			if(_hypeAudio.options.startAheadOfPlayback != true) {
				_hypeAudio._start();
			}
		}
	});

	_hypeAudio.pause = (function () {
		if(_hypeAudio.isLoaded != true) {
			_hypeAudio.playWhenFinishedLoading = false;
			return;
		}

		_hypeAudio._stop();
	});
	
	_hypeAudio._start = (function () {
		try {
			if(_hypeAudio.source != null) {
				if(_hypeAudio.source['noteOn'] != null) {
					_hypeAudio.source['noteOn'](0);
				} else {
					_hypeAudio.source['start'](0);
				}
			}
		} catch (e) {	}
	});
	
	_hypeAudio._stop = (function () {
		try {
			if(_hypeAudio.source != null) {
				if(_hypeAudio.source['noteOff'] != null) {
					_hypeAudio.source['noteOff'](0);
				} else {
					_hypeAudio.source['stop'](0);
				}
			}
		} catch (e) {	}
	});
	
	_hypeAudio.validSourceURL = (function () {
		if(_hypeAudio.resolvedValidSourceURL != null) {
			return _hypeAudio.resolvedValidSourceURL;
		}
		
		var dummyAudioElement = document.createElement("audio");
	
		var sortedMimeTypes = _hypeAudio.sortedMimeTypes();
		for(var i = 0; i < sortedMimeTypes.length; i++) {
			var mimeType = sortedMimeTypes[i];
			_hypeAudio.resolvedValidSourceURL = _hypeAudio.sourceURLsByMimeType[mimeType];
			if(dummyAudioElement.canPlayType(mimeType) != "no" && dummyAudioElement.canPlayType(mimeType) != "") {
				break;
			}
		}
		
		return _hypeAudio.resolvedValidSourceURL;
	});
}	

${ifdef supportInternetExplorer6789}
function HypeAudio_QuickTime(oid, sourceURLsByMimeType) {
	var _hypeAudio = this;
	HypeAudio_allAudios[oid] = _hypeAudio;

	_hypeAudio.setupAudioElement = (function (errorCallback) {
		var audioElement = document.createElement("embed");
		_hypeAudio.audioElement = audioElement;
		var sortedMimeTypes = _hypeAudio.sortedMimeTypes();
		for(var i = 0; i < sortedMimeTypes.length; i++) {
			var mimeType = sortedMimeTypes[i];
			if(mimeType == "audio/ogg") {
				continue;
			}
			
			var sourceURL = _hypeAudio.sourceURLsByMimeType[mimeType];
			audioElement.setAttribute("src", sourceURL);
			audioElement.setAttribute("controller", "True");
			audioElement.setAttribute("autoplay", "False");
			audioElement.setAttribute("autostart", "False");
			audioElement.setAttribute("width", "0");
			audioElement.setAttribute("height", "0");
			audioElement.style.width = "0px";
			audioElement.style.height = "0px";
			break;
		}
		document.body.appendChild(audioElement);
		
		return audioElement;
	});

	_hypeAudio.load = (function (successCallback, errorCallback) {
		if(_hypeAudio.audioElement == null) {
			_hypeAudio.setupAudioElement(errorCallback);
		}
		if(successCallback != null) {
			successCallback(_hypeAudio);
		}
	});
	
	_hypeAudio.play = (function () {
		if(_hypeAudio.audioElement == null) {
			_hypeAudio.setupAudioElement(null);
		}
		try {
			_hypeAudio.audioElement['SetIsLooping'](_hypeAudio.loop);
		} catch (err) {	}
		try {
			_hypeAudio.audioElement['Play']();
		} catch (err) {
		    window.setTimeout(function() { _hypeAudio.play(); }, 100);
		}
	});

	_hypeAudio.pause = (function () {
		if(_hypeAudio.audioElement == null) {
			return;
		}

		try {
			_hypeAudio.audioElement['Stop']();
		} catch (err) {
		    window.setTimeout(function() { _hypeAudio.pause(); }, 100);
		}
	});
}
${endif}
