(function() {
if (typeof SEETOO == "undefined"  || typeof SEETOO.API != "undefined") {
	return;
}

SEETOO.API = {

	addEventListener: function(type, data, fn) {
		getEventDispatcher().bind(type, data, fn);
	},

	removeEventListener: function(type, fn) {
		getEventDispatcher().unbind(type, fn);
	},

	setSession: function(id) {
		sessionID = id;
	},

	setClient: function(id) {
		clientID = id;
		$.post(URLS.LOG_SESSION_CLIENT, {
			sessionID: sessionID,
			clientID: clientID,
			clientType: clientType,
			instanceID: instanceID
		});

		$(window).bind('beforeunload', function() {
			$.post(URLS.LOG_SESSION_CLIENT_EVENT, {
				sessionID: sessionID,
				clientID: clientID,
				instanceID: instanceID,
				eventType: EVENT_TYPES.EXIT,
				info: ''
			});
		});
	},

	poke: function(command) {
		$.post(URLS.LOG_SESSION_CLIENT_EVENT, {
			sessionID: sessionID,
			clientID: 'poke',
			instanceID: instanceID,
			eventType: EVENT_TYPES.COMMAND_LINE,
			info: command || document.location.href
		});
	},

	sumSession: function() {
		if (sessionID) $.post(URLS.SUM_SESSION, { sessionID: sessionID });
	},

	parseStreamerMessage: function(message) {
		var commandSeperator = message.indexOf(',');
		var command = message.substring(0, commandSeperator);
		var commandData = message.substring(commandSeperator + 1, message.length);

		switch (command) {
			case STREAMER_COMMANDS.UPDATE_PROGRESS:
				parseStreamerProgress(commandData);
				break;
			case STREAMER_COMMANDS.UPDATE_START_POSITION:
				parseStreamerStartPossition(commandData);
				break;
			case STREAMER_COMMANDS.UPDATE_MEDIA_DATA:
				parseMediaData(commandData);
				break;
			case STREAMER_COMMANDS.STREAMER_MESSAGE:
				parseStreamerMessage(commandData);
				break;
			case STREAMER_COMMANDS.UPDATE_STATUS:
				parseStreamerStatus(commandData);
				break;
			default: // do nothing
		}
	},

	getMediaDuration: function() {
		return mediaDuration;
	},

	getMediaProgress: function() {
		return mediaProgress;
	},

	getMediaTitle: function() {
		return mediaTitle;
	},

	changeMedia: function(streamName, fileName, title) {
		clearMediaData();
		var request = 'request:changeMedia' +
			'?streamName=' + encodeURIComponent(streamName) +
			'&source=' + encodeURIComponent(fileName) +
			'&title=' + encodeURIComponent(title);
		SEETOO.APP.Addon.get().execute('protocol RequestFromServer ' + request);
		$.post(URLS.LOG_SESSION_CLIENT_EVENT, {
			sessionID: sessionID,
			clientID: clientID,
			instanceID: instanceID,
			eventType: EVENT_TYPES.SELECT_FILE,
			info: fileName
		});
	},

	stopMedia: function() {
		if (mediaFileName.length == 0) return;
		SEETOO.APP.Addon.get().execute('protocol Seek ' + (mediaDuration - 1));
		$.post(URLS.LOG_SESSION_CLIENT_EVENT, {
			sessionID: sessionID,
			clientID: clientID,
			instanceID: instanceID,
			eventType: EVENT_TYPES.PAUSE,
			info: ''
		});
	}

};

var clientType = 7;
var instanceID = (new Date()).getTime().toString();
var sessionID;
var clientID;

var mediaDuration;
var mediaProgress;
var mediaTitle;
var mediaFileName;
var mediaStartPosition;

var retryingCount = 0;

var mediaCompletedTimeout;

var parseStreamerStatus = function(data) {
	if (data.toLowerCase().indexOf('error') == 0) {
		clearMediaData();

		if (data.indexOf('0x1020') > 0 || data.indexOf('4028') > 0 ||
		data.indexOf('0x1021') > 0 || data.indexOf('4029') > 0 ||
		data.indexOf('0x1016') > 0 || data.indexOf('4118') > 0 ||
		data.indexOf('0x1026') > 0 || data.indexOf('4134') > 0) {
			if (retryingCount < 3) {
				retryingCount++;
				dispatchEvent(SEETOO.API.Events.ON_RETRYING, data.substr(data.toLowerCase().indexOf('error:') + 6));
			} else {
				dispatchEvent(SEETOO.API.Events.ON_FATAL, data.substr(data.toLowerCase().indexOf('error:') + 6));
			}
		} else {
			dispatchEvent(SEETOO.API.Events.ON_ERROR, data.substr(data.toLowerCase().indexOf('error:') + 6));
		}
	} else if (data.toLowerCase().indexOf('clos') == 0) {
		dispatchEvent(SEETOO.API.Events.ON_CLOSE);
	}
}

var parseStreamerStartPossition = function(data) {
	mediaStartPosition = parseInt(data, 10);
	if (mediaDuration > 1) parseStreamerProgress(data);
}

var parseStreamerProgress = function(data) {
	mediaProgress = parseInt(data, 10);

	if (mediaProgress < 0) {
		return;
	} else if (mediaProgress > mediaDuration && mediaDuration > 0) {
		dispatchEvent(SEETOO.API.Events.MEDIA_COMPLETED);
	} else {
		dispatchEvent(SEETOO.API.Events.MEDIA_PROGRESS_CHANGED, mediaProgress);
	}
};

var parseMediaData = function(data) {
	clearMediaData();

	try {
		var isEmpty = data.indexOf('<stream>') < 0;

		if (isEmpty && data.indexOf('<multipleInstances>yes</multipleInstances>') > 0) {
			dispatchEvent(SEETOO.API.Events.ON_STREAMER_MULTIPLE_INSTENCES, []);
			return;
		}

		if (isEmpty) {
			if (retryingCount == 0) {
				dispatchEvent(SEETOO.API.Events.ON_READY);
				setTimeout(function() {
					var request = 'request:setIni?ini=iniFile.php';
					SEETOO.APP.Addon.get().execute('protocol RequestFromServer ' + request);
				}, 50);
			}

			return;
		}

		var sourceIndex = data.indexOf('<source>');

		if (sourceIndex < 0) {
			return;
		}

		retryingCount = 0;

		var titleIndex = data.indexOf('<title>', sourceIndex);
		titleIndex > 0 && (mediaTitle = data.substring(titleIndex + '<title>'.length, data.indexOf('</', titleIndex)));

		var fileIndex = data.indexOf('<file>', sourceIndex);

		if (fileIndex > 0) {
			var nameIndex = data.indexOf('<name>', fileIndex);
			nameIndex > 0  && (mediaFileName = data.substring(nameIndex + '<name>'.length, data.indexOf('</', nameIndex)));
		}

		var durationIndex = data.indexOf('<duration>');

		if (durationIndex > 0) {
			mediaDuration = parseInt(data.substring(durationIndex + '<duration>'.length, data.indexOf('</', durationIndex)), 10);
			dispatchEvent(SEETOO.API.Events.ON_MEDIA_READY);
		}
	} catch (ex) {}
};

var parseStreamerMessage = function(data) {
	if (data.indexOf('streamStatus') > 0) {
		if (data.indexOf('videoStarted') > 0) {
			clearTimeout(mediaCompletedTimeout);
			dispatchEvent(SEETOO.API.Events.MEDIA_STARTED);
		} else {
			var timeLeft = mediaDuration - mediaProgress + 1;

			if (mediaProgress > 0 && timeLeft > 0 && timeLeft < 5000) {
				clearTimeout(mediaCompletedTimeout);
				mediaCompletedTimeout = setTimeout(function() { dispatchEvent(SEETOO.API.Events.MEDIA_COMPLETED); }, timeLeft);
			}

			dispatchEvent(SEETOO.API.Events.MEDIA_STOPPED);
		}
	} else if (data.indexOf('audioStatus')) {
		if (data.indexOf('Off')) {
			dispatchEvent(SEETOO.API.Events.AUDIO_DISABLED);
		} else {
			dispatchEvent(SEETOO.API.Events.AUDIO_ENABLED);
		}
	}
};

var clearMediaData = function() {
	mediaDuration = 0;
	mediaProgress = 0;
	mediaTitle = '';
	mediaFileName = '';
	dispatchEvent(SEETOO.API.Events.MEDIA_PROGRESS_CHANGED, mediaProgress);
};

SEETOO.API.Events = {
	MEDIA_DATA_CHANGED: 'mediaDataChanged.SEETOO_API',
	MEDIA_PROGRESS_CHANGED: 'mediaDataChanged.SEETOO_API',
	MEDIA_STARTED: 'mediaStarted.SEETOO_API',
	MEDIA_STOPPED: 'mediaStopped.SEETOO_API',
	MEDIA_COMPLETED: 'mediaCompleted.SEETOO_API',
	AUDIO_ENABLED: 'audioEnabled.SEETOO_API',
	AUDIO_DISABLED: 'audioDisabled.SEETOO_API',
	ON_STREAMER_MULTIPLE_INSTENCES: 'onStreamerMultipleInstances.SEETOO_API',
	ON_READY: 'onReady.SEETOO_API',
	ON_MEDIA_READY: 'onMediaReady.SEETOO_API',
	ON_CLOSE: 'onClose.SEETOO_API',
	ON_ERROR: 'onError.SEETOO_API',
	ON_FATAL: 'onFatal.SEETOO_API',
	ON_RETRYING: 'onRetrying.SEETOO_API'
};

var URLS = {
	LOG_SESSION_CLIENT: 'stats/LogSessionClient.php',
	LOG_SESSION_CLIENT_EVENT: 'stats/LogSessionClientEvent.php',
	SUM_SESSION: 'stats/SumSession.php'
};

var STREAMER_COMMANDS = {
	UPDATE_MEDIA_DATA: 'updateMediaData',
	UPDATE_STATUS: 'updateStreamerStatus',
	UPDATE_START_POSITION: 'streamerCommandStartPos',
	UPDATE_PROGRESS: 'streamerCommandProgress',
	STREAMER_MESSAGE: 'streamerMessage'
};

var EVENT_TYPES = {
	LOGIN: '1',
	LOGOUT: '2',
	JOIN: '3',
	LEAVE: '4',
	START: '5',
	STOP: '6',
	PLAY: '7',
	PAUSE: '8',
	SEEK: '9',
	REJECT: '10',
	SELECT_FILE: '11',
	SELECT_BUDDY: '12',
	BANDWIDTH: '13',
	ERROR: '14',
	WARNING: '15',
	STATUS: '16',
	CHANGE_STREAM: '17',
	EXIT: '18',
	MEDIA_DATA: '19',
	VERSION: '20',
	COMMAND_LINE: '21',
	PROCESS_FILE: '22',
	ICQ_SHARE: '23',
	ICQ_INVITE: '24',
	ICQ_USER: '25',
	ICQ_STANDALONE: '26',
	AIM_USER: '27',
	AIM_INVITE_USER: '28',
	STARTING_STREAMER: '29',
	RESTARTING_STREAMER: '30',
	USER: '31',
	USER_ID: '32'
}

var eventDispatcher;
var getEventDispatcher = function() {
	if (!eventDispatcher) {
		var el = document.createElement('div');
		document.body.appendChild(el);
		eventDispatcher = $(el);
	}

	return eventDispatcher;
};

var dispatchEvent = function(type, data) {
	if (typeof data != "array") {
		data = [data];
	}

	getEventDispatcher().triggerHandler(type, data);
};

var eventWrapper = function(eventName, callback) {
	var callbackWrapper = function(event, json) {
		try {
			callback.call(callback, json);
		} catch (ex) {}

		event.data.call();
	};

	var gc = function(event) {
		SEETOO.API.removeEventListener(eventName, callbackWrapper);
	};

	SEETOO.API.addEventListener(eventName, gc, callbackWrapper);
};

})();
