/**
 * Bulk upload callbacks
 * Lalit 
 * www.lalit.org
 */
var CallBacks = {};

/*
	File Object
    * id - the auto-generated unique id for each file
    * name - actual filename
    * size - filesize
    * type - filetype
    * creationDate - fhe file creation date
    * creator - file creator
*/

// Create a empty form list to store all the forms.
CallBacks.formList = [];
CallBacks.currFile = '';

/**
 * Added a delay function before call to acutal UI function to prevent the race
 * condition in IE which causes swfu to be accessed as null sometimes.
 */
CallBacks.flash_loaded = function(){
	setTimeout(CallBacks.flash_loaded_race, 1500);
};

CallBacks.flash_loaded_race = function() {
	try {
		//Logging (3 lines)
		Folder.swfu.swfLoadTime  = new Date().getTime();
		Folder.swfu.target  = swfu.getSetting('upload_target_url');
		Folder.swfu.movieID = swfu.movieName;

		// Lalit --> swfu6
		// Directly acces the div. the target  property is not valid here
		//alert('swfu: ' + swfu);
		t = $('UploadButton');
		t.update('');
	
		s = document.createElement('input');
		s.type = 'button';
		s.onclick = function() {
			//Logging (1 lines)
			Folder.swfu.publishTime = new Date().getTime();
			CallBacks.publish_all();
		};
		s.value = 'Publish All';
		s.id = swfu.movieName + "PublishBtn";
		s.className = 'publishbtn';
		t.appendChild(s);
		if(!CallBacks.show_publish) { 
		      $(s).hide();
		}
		
		s = document.createElement('input');
		s.type = 'button';
		s.onclick = function() {
			//Logging (1 lines)
			Folder.swfu.browseTime = new Date().getTime();
			swfu.browse();
			return false;
		};
		s.value = 'Browse and select files...';
		s.id = swfu.movieName + "BrowseBtn";
		s.className = 'browsebtn';
		t.appendChild(s);
		t.appendChild(document.createTextNode(' (Use Ctrl key to select multiple files)'));
		
		browse = s;
	
		/*
		// Add upload btn if auto upload not used
		s = document.createElement('input');
		s.type = 'button';
		s.onclick = function() { swfu.upload(); return false;};
		s.value = 'Upload files';
		s.id = swfu.movieName + "UploadBtn";
		$(s).hide()
		t.appendChild(s);
		t.appendChild(document.createTextNode(' '));

		// open the select file dialog as soon as the page loads
		//browse.click();
	
		// Add upload btn if auto upload not used
		if(swfu.getSetting("auto_upload") == false) {
			s = document.createElement('input');
			s.type = 'button';
			s.onclick = function() { CallBacks.cancelQueue(); return false;};
			s.value = 'Remove All';
			s.id = swfu.movieName + "cancelqueuebtn";
			t.appendChild(s);
		}
		*/

	} catch(e) {
		$('UploadButton').update('<div style="font-size:14px;color:#cc3333;padding:3px;line-height:1.8">We have detected that your browser\'s Flash version does not support our Bulk Upload feature.<br>Go <a href="/singleupload" class="blue_link_bold">here</a> to upload your files using <a href="/singleupload" class="blue_link_bold">Single Upload</a>.</div>');
	}
};

CallBacks.upload_file_queued = function(file, queuelength) {
	/* limit num of files to 1
	if (queuelength > 1) {
		swfu.cancelFile(file.id);
		return;
	} */

	// Lalit --> swfu6
	// so that the file_id is sent along the file to the server
	swfu.addFileParam(file.id, 'file_id', file.id);	

	Folder.initFile(file);
	
	var listingfiles = $('UploadFileList');

	if(!listingfiles.getElementsByTagName("ul")[0]) {	
		var ul = document.createElement("ul")
		listingfiles.appendChild(ul);
	}
	
	listingfiles = listingfiles.getElementsByTagName("ul")[0];
	
    li = "<li class='FileItem' id='"+ file.id +"'>";
    //var li = document.createElement("li");
    //li.id = file.id;
    //li.className = "FileItem";
    li += "<div class='percent' id='" + file.id + "_percent'>0%</div>";
    li += "<div class='progress'><a id='" + file.id + "_deletebtn' class='cancelbtn' href='javascript:swfu.cancelUpload(\"" + file.id + "\");'><!-- IE --></a>Uploading <b>'"
            + file.name.escapeHTML() + "'</b> (" + Math.ceil(file.size/1024) + "kb)"
            + "<span class='progressBar' id='" + file.id + "_progress'></span></div>";
    li += "</li>";
    
    //listingfiles.appendChild(li);
    //alert(li.toString());
    new Insertion.Top(listingfiles, li);


	//comment the following line if you want to allow multiple files
	//$(swfu.movieName + "BrowseBtn").hide();
	//if (swfu.getSetting("auto_upload") == false) {
		//$(swfu.movieName + "UploadBtn").show();
	//}

	//Publish buton -- only shows if all files have successfuly been uploaded
	$(swfu.movieName + 'PublishBtn').hide();
	$('settingsBox').hide();
	//$(swfu.movieName + "cancelqueuebtn").show();
};

CallBacks.upload_file_cancel = function(file, queuelength) {
	
	//alert( "cancel " + queuelength)
	/* limit num of files to 1 
	if (queuelength > 1) {
		return;
	}*/

	var li = $(file.id);
	Effect.DropOut(li);

	//Logging (2 line)
	Folder.cancel(file.id);	// set the file cancel time
	Folder.add(file);	// add the file to the folder, remember to do this baby
	
	/* last file cancelled
	if (queuelength == 0) {
		$(swfu.movieName + "BrowseBtn").show();
		$(swfu.movieName + "UploadBtn").hide();
	}
	 */
};

CallBacks.upload_file_start = function(file, position, queuelength) {
	var li = $(file.id);
	li.addClassName("uploadStarted");
};

CallBacks.upload_progress = function(file, bytesLoaded) {
	
	var progress = $(file.id + "_progress");
	var percent = Math.ceil((bytesLoaded / file.size) * 100);
	progress.style.background = "#ddd url(http://public.slideshare.net/images/bulk_upload_progress.png) no-repeat -" + Math.ceil(650 - percent * 6.5) + "px 0";
	$(file.id + "_percent").update(percent + '%');

	//Logging (6 line)
	//we use setTimeout to avoid 0% stuck issue with Macs.
	//	if (CallBacks.currFile != file.id) {
	//		CallBacks.currFile  = file.id;
			setTimeout(function(){
				Folder.startFile(file);
			}, 100);
	//	}
	
};

CallBacks.upload_error = function(text, file, msg) {
	//Logging (7 lines)
	file._error = {
		time: new Date().getTime(),
		code: text,
		mesg: msg
	};
	file._endTime = null;	// set the end time of upload
	Folder.add(file);	// add the file to the folder
	
    li = $(file.id);
    li.removeClassName("uploadStarted");
	li.addClassName("uploadFailed");
	li.update("<div class='head'>Upload of <b>'" + file.name.escapeHTML() + "'</b> has failed! Please try again.<br>If it fails again, please use the <a href='/singleupload' class='blue_link_bold'>single upload</a> to upload your files.</div>");
};
            

CallBacks.cancelQueue = function() {
	swfu.cancelQueue();
	//$(swfu.movieName + "UploadBtn").hide();
	//$(swfu.movieName + "cancelqueuebtn").hide()";
};

CallBacks.upload_queue_complete = function(file) {
	//$(swfu.movieName + "UploadBtn").hide();
	//Publish buton -- onlyhows if all files have successfuly been uploaded
	$(swfu.movieName + 'PublishBtn').show();
	$('settingsBox').show();	
};


CallBacks.remove_file_manual = function(file_id) {
	var li = $(file_id);
	Effect.SwitchOff(li);
	// remove the form from the list of forms.
	CallBacks.formList = CallBacks.formList.without('form_' + file_id);
};

CallBacks.after_effect = function(l, h) {
	li = l;
	html = h;
	return function() {
		li.update(html);
		new Effect.Opacity(li, {duration:1.5, from:0.0, to:1.0});
	};
};

/**
 * Copies the default language to all slideshows
 */
CallBacks.set_language = function() {
	var feilds = document.getElementsByName('slideshow[language]');
	var selected_language = $('ss_language').value
	$A(feilds).each(function(f){
		f.value = selected_language;
	});
};

/**
 * Copies the selected Privacy Level to all the slideshows
 */
CallBacks.set_private_level = function(user) {
	if($('ss_private_type').value == 'new') {
		//$('ss_private_type').selectedIndex = 1;
		window.open('/' + user + '/contacts/lists', '_blank');
		return;
	}
	var feilds = document.getElementsByName('private_type');
	var selected_level = $('ss_private_type').value
	$A(feilds).each(function(f){
		f.value = selected_level;
	});
};

/**
 * Opnes a create list popup
 */
CallBacks.create_list = function(fid, user) {
	//alert(fid + user);
	if($('private_type_' + fid).value == 'new') {
		$('private_type_' + fid).selectedIndex = 1;
		window.open('/' + user + '/contacts/lists', '_blank');
	}
};

CallBacks.publish_file = function(file_id) {
	CallBacks.formList = CallBacks.formList.without('form_' + file_id);
	lit = $(file_id);
	lit.update('<div class=head>Sending request...</div>');
	lit.removeClassName('uploadCompleted');
	lit.addClassName('uploadProgress');
	Folder.publish(file_id);
	if (CallBacks.formList.length == 0) {
		$(swfu.movieName + 'PublishBtn').hide();
		$('settingsBox').hide();
	}
};


/**
 * Publishes all the unpublished files :)
 */
CallBacks.publish_all = function() {
	CallBacks.set_language();
	CallBacks.formList.each(function(f) {
		//alert(f);
    	CallBacks.formList = CallBacks.formList.without(f);
		new Ajax.Request('/publish', {
				asynchronous:true, 
				parameters:Form.serialize(f)
			}
		);

		//Logging (1 lines)
		Folder.publish(f);
        lit = $(f.sub('form_', ''));
        lit.update('<div class=head>Sending request...</div>');
        lit.removeClassName('uploadCompleted');
        lit.addClassName('uploadProgress')
	});
	$(swfu.movieName + 'PublishBtn').hide();
	$('settingsBox').hide();
};

/**
 * Folder: Keeps the reference to all the files and their debug info, 
 * so that we can send that back to the server.
 */
var Folder = {
	INCOMPLETE: 0,		//file has not been added to the folder and not ready to be sent to server.
	COMPLETE : 1,		//file has been added to the folder and ready to be sent to server.
	uploaded : 0,		//if the folder has been uploaded atleast once (the swfu metadata has been logged)
	files : [],
	// initial values
	swfu : {
		publishTime:0,
		browseTime:0, 
		pageLoadTime:0,
		swfLoadTime:0,
		movieID: null, 
		target:null,
		userAgent:null,
		session:null
	},
	
	// resets the folder.
	// used when we have sent the data to the server so if the user decides to upload a few more
	// files, we can log and send them to the server.
	empty : function() {
		Folder.files = [];
	},

	// intitalize the file when it is first queued
	initFile : function(file) {
		var newFile = {};
		newFile.id = file.id;
		newFile.name = '';
		newFile.size = 0;
		newFile.type = '';
		newFile._startTime = 0;
		newFile._endTime = 0;
		newFile._error = {time:null, code:null, mesg:null};
		newFile._cancelTime = 0;
		newFile._publishTime = 0;
		newFile._deleteTime = 0;
		newFile.__status = Folder.INCOMPLETE;
		Folder.files.push(newFile);
	},
	
	//add a file to the folder
	add: function(file) {
		// extend the old file object so that all the values of curr file object are considered.
		var oldFile = Folder.find(file.id)
		Object.extend(oldFile, file);
		oldFile.__status = Folder.COMPLETE;
	},
	
	// convert time to human form
	time : function(date) {
		return date.toDateString() + " "  + date.toLocaleTimeString()
	},
	
	//start time for this file.
	startFile : function(file_id){
		var file = Folder.find(file_id);
		if (file && file._startTime == 0) {
			file._startTime = new Date().getTime();
		}
	},
	
	// if the file has been published by the user
	publish : function(file_id) {
		var file = Folder.find(file_id);
		if (file != null) {
			file._publishTime = new Date().getTime();
		}
		// TODO: can you call Folder.upload() now?
		if (CallBacks.formList.length == 0 && Folder.allFilesComplete())  {
			Folder.upload();
		}
	},
	
	// called when the user chooses to delete the file after uploading.
	remove : function(file_id) {
		var file = Folder.find(file_id);
		if (file != null) {
			file._deleteTime = new Date().getTime();
		}
		// TODO: can you call Folder.upload() now?
		if (CallBacks.formList.length == 0 && Folder.allFilesComplete())  {
			Folder.upload();
		}
	},
	
	// if the user cancelled the file upload while it was being uploaded
	cancel : function(file_id) {
		var file = Folder.find(file_id);
		if (file != null) {
			file._cancelTime = new Date().getTime();
		}
		if (CallBacks.formList.length == 0 && Folder.allFilesComplete())  {
			Folder.upload();
		}		
	},
	
	// set sime default values for a file
	find : function(file_id) {
		/*
		var file = $A(Folder.files).find(function(f) {
			return f.id == file_id;
		});
		*/
		//plane vanilla to speedup things.
		var totalFiles = Folder.files.length;
		for (i = 0; i < totalFiles; i++) {
			if (Folder.files[i].id == file_id) {
				return Folder.files[i];
			}
		}
		return null;
	},
	
	// serialize the data to be sent to the server
	serialize : function() {
		var data = {};
		data['swfu[movieID]']		= Folder.swfu.movieID;
		data['swfu[session]']		= Folder.swfu.session;
		data['swfu[target]']		= Folder.swfu.target;
		data['swfu[userAgent]']		= Folder.swfu.userAgent;
		data['swfu[flashVer]']		= Folder.getFlashVersion();
		data['swfu[swfLoadTime]']	= Folder.swfu.swfLoadTime;
		data['swfu[pageLoadTime]']	= Folder.swfu.pageLoadTime;
		data['swfu[publishTime]']	= Folder.swfu.publishTime;
		data['swfu[browseTime]']	= Folder.swfu.browseTime;
		
		for (i=0; i<Folder.files.length; i++) {
			data['files['+i+'][id]']			= Folder.files[i].id;
			data['files['+i+'][name]']			= Folder.files[i].name;
			data['files['+i+'][size]']			= Folder.files[i].size;
			data['files['+i+'][type]']			= Folder.files[i].type;
			data['files['+i+'][startTime]']		= Folder.files[i]._startTime;
			data['files['+i+'][endTime]']		= Folder.files[i]._endTime;
			data['files['+i+'][cancelTime]']	= Folder.files[i]._cancelTime;
			data['files['+i+'][deleteTime]']	= Folder.files[i]._deleteTime;
			data['files['+i+'][publishTime]']	= Folder.files[i]._publishTime;
			data['files['+i+'][error_time]']	= Folder.files[i]._error['time'];
			data['files['+i+'][error_code]']	= Folder.files[i]._error['code'];
			data['files['+i+'][error_text]']	= Folder.files[i]._error['mesg'];
		}
		
		return data;
	},
	
	// send the folder to the server
	// should be called when Publish All is clicked
	// should be called when all the files have been publised :) (one by one)
	upload : function() {
		// bye bye! if already uploaded once and no new files to upload 
		if (Folder.uploaded == 1 && Folder.files.length == 0) {
			return;
		}

		//get serialized data
		var params = Folder.serialize();
		new Ajax.Request('/uploadlogs',{method:'post', parameters:params});

		//set uploaded = 1 => alteast uploaded once.
		Folder.uploaded = 1;
		//reset the folder and get ready for next round of logging
		Folder.empty();
	},
	
	regenOldUploads : function() {
		if (CallBacks.formList.length != 0) {
			$A(CallBacks.formList).each(function(f) {
				// dummy file object
				var newFile = {};
				newFile.id = f.substring(5);	//remove the 'form_' from the id

				// add a new file in the folder.				
				Folder.initFile(newFile);
				
				// mark the status complete
				newFile = Folder.find(newFile.id);
				newFile.__status = Folder.COMPLETE;
				newFile._startTime = 0;
			});
		}
	},
	
	getFlashVersion : function() {
		try {
			var v = deconcept.SWFObjectUtil.getPlayerVersion();
			return v.major + ',' + v.minor + ',' + v.rev + ',0';
		} catch(e) {
			// ssshh!
		}
	},
	
	allFilesComplete : function() {
		var file = $A(Folder.files).find(function(f) {
			return (f.__status == Folder.INCOMPLETE);
		});
		return (file == null);
	}
};


/**
 *  Base64 encode / decode
 *  http://www.webtoolkit.info/
 */
var Base64 = {

	// private property
	_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

	// public method for encoding
	encode : function (input) {
		var output = "";
		var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
		var i = 0;

		input = Base64._utf8_encode(input);

		while (i < input.length) {

			chr1 = input.charCodeAt(i++);
			chr2 = input.charCodeAt(i++);
			chr3 = input.charCodeAt(i++);

			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;

			if (isNaN(chr2)) {
				enc3 = enc4 = 64;
			} else if (isNaN(chr3)) {
				enc4 = 64;
			}

			output = output +
			this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
			this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

		}

		return output;
	},

	// public method for decoding
	decode : function (input) {
		var output = "";
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;

		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

		while (i < input.length) {

			enc1 = this._keyStr.indexOf(input.charAt(i++));
			enc2 = this._keyStr.indexOf(input.charAt(i++));
			enc3 = this._keyStr.indexOf(input.charAt(i++));
			enc4 = this._keyStr.indexOf(input.charAt(i++));

			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;

			output = output + String.fromCharCode(chr1);

			if (enc3 != 64) {
				output = output + String.fromCharCode(chr2);
			}
			if (enc4 != 64) {
				output = output + String.fromCharCode(chr3);
			}
		}

		output = Base64._utf8_decode(output);

		return output;

	},

	// private method for UTF-8 encoding
	_utf8_encode : function (string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";

		for (var n = 0; n < string.length; n++) {

			var c = string.charCodeAt(n);

			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}

		}

		return utftext;
	},

	// private method for UTF-8 decoding
	_utf8_decode : function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;

		while ( i < utftext.length ) {

			c = utftext.charCodeAt(i);

			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}

		}
		return string;
	} 
};