if (!Function.prototype.bind) {
  Function.prototype.bind = function (obj)
  {
    var func = this;
    return function () {return func.apply(obj, arguments);};
  };
}


function PushFriendBubble() {
}

PushFriendBubble.prototype.setHandlers = function() {
	$('#push_your_friend').submit(this.onSubmit.bind(this));
}

PushFriendBubble.prototype.onSubmit = function() {
	var nickname = jQuery.trim($('#push_your_friend_nick').val());
	if (nickname != '') {
		document.location = '/'+nickname+'/';
	}
	return false;
}

function PushmeForm() {
	this.uploader = null;
}

PushmeForm.prototype.setUploader = function(uploader) {
	this.uploader = uploader;
}

PushmeForm.prototype.clearValidation = function() {
	$('#push_form_too_long_message').hide();
	$('#push_form_cannot_store_attachment').hide();
	$('#push_form_no_message').hide();
	$('#push_form_no_signature').hide();
	if ($('#push_form_wrong_captcha').length > 0) {
		$('#push_form_wrong_captcha').hide();
	}
}

PushmeForm.prototype.validate = function() {
	var isFormValid = true;
	if (jQuery.trim($('#message').val())=='') {
		$('#push_form_no_message').show();
		isFormValid = false;
	}
	
	if (jQuery.trim($('#signature').val())=='') {
		$('#push_form_no_signature').show();
		isFormValid = false;
	}

	if ($('#captcha').length > 0 && jQuery.trim($('#captcha').val())=='') {
		$('#push_form_wrong_captcha').show();
		isFormValid = false;
	}
	
	return isFormValid;
}

PushmeForm.prototype.enableSubmitButton = function(doEnable) {
	if (doEnable) {
		$('#send_message_submit').removeAttr('disabled');
		$('#pushme_iphone_submit').removeAttr('disabled');
	} else {
		$('#send_message_submit').attr('disabled','disabled');
		$('#pushme_iphone_submit').attr('disabled','disabled');
	}
}

PushmeForm.prototype.showInProgress = function(isInProgress) { 
	if (isInProgress) {
		$('#push_in_progress').css('visibility','visible');
		this.enableSubmitButton(false);
	} else { 
		$('#push_in_progress').css('visibility','hidden');
		this.enableSubmitButton(true);
	}
}

PushmeForm.prototype.showSentSuccess = function()  {
	$('#send_result').show();
	$('#send_message_form').hide();
	$('#pushme_iphone').hide();
}

PushmeForm.prototype.onSuccess = function(data, status) {
	eval("var obj="+data); // FIXME

	this.showInProgress(false);

	if ('success' == obj.status) {
		this.showSentSuccess();
	} else if ('error' == obj.status) {
		var errorShown=false;
		if (obj.error == 'noMessage') {
			errorShown=true;
			$('#push_form_no_message').show();
		}
		if (obj.error == 'noSignature') {
			errorShown=true;
			$('#push_form_no_signature').show();
		}
		if (obj.error == 'tooLong') {
			errorShown=true;
			$('#push_form_too_long_message').show();
		}
		if (obj.error == 'wrongCaptcha') {
			errorShown=true;
			$('#push_form_wrong_captcha').show();
			$('#captchaImg').attr('src', '/captcha/?id='+obj.captchaId);
			$('#captchaId').attr('value', obj.captchaId);
		}
		if (obj.error == 'cannotStoreAttachment') {
			errorShown=true;
			$('#push_form_cannot_store_attachment').show();
		}

		if (!errorShown) {
			this.showError("Unknown error happened. Try again later.");
		}		
	}
}

PushmeForm.prototype.clearError = function() {
	$('#send_message_error_result').hide();
}

PushmeForm.prototype.showError = function(errorString) {
	$('#send_message_error_result').html(errorString);
	$('#send_message_error_result').show();
}

PushmeForm.prototype.onFailure = function() {
	this.showInProgress(false);
	this.showError("Error happened. Try again later.");
}

PushmeForm.prototype.setHandlers = function() {
	this.clearValidation();
	this.showInProgress(false);
	this.clearError();

	$('#send_message_form').submit(this.onSubmit.bind(this));
	// FIXME  onsubmit for the form
	$('#pushme_iphone').submit(this.onSubmit.bind(this));

	$('#message').bind("change keyup", this.updateLength.bind(this));
	$('#signature').bind("change keyup", this.updateLength.bind(this));
	this.updateLength();

	$('#message').focus();
}

PushmeForm.prototype.onSubmit = function() {
	this.clearValidation();
	this.clearError();

	if (!this.validate()) {
		//return false;
	}

	this.showInProgress(true);
	var postArguments = {
		'message':$('#message').val(),
		'signature':$('#signature').attr('value'),
		'nickname':$('#nickname').val(),
		'captcha[input]':$('#captcha').val(),
		'captcha[id]':$('#captchaId').val()
	};
	if (this.uploader) {
		var uploadedFilenames = this.uploader.uploadedFilenames();
		if (uploadedFilenames.length>0) {
			postArguments.filenames = uploadedFilenames.join(',');
		}
	}

	$.ajax({
		'type':'POST',
		'url': '/z/ajax/pushme/',
		'data': postArguments,
		'error' : this.onFailure.bind(this),
		'success':this.onSuccess.bind(this)
	});
	return false;
}


PushmeForm.prototype.updateLength = function() {
	var maxLength = 500;

	var charsLeft = maxLength - $('#message').val().length - $('#signature').val().length;
	
	if (charsLeft < 0) {
		this.enableSubmitButton(false);
		charsLeft = 0;
	} else {
		this.enableSubmitButton(true);
	}
	
	$('#chars_left').html(charsLeft);

	if (charsLeft == 0) {
		$('#send_message_characters > span').attr('id','red');
	} else if (charsLeft < 50) {
		$('#send_message_characters > span').attr('id','orange');
	} else {
		$('#send_message_characters > span').attr('id','gray');
	}

	var percent = 100-(charsLeft/500*100);
	if (percent < 8) {
		percent = 8;
	}
	$('#send_message_characters > span > span').css('width',percent+'%');
}




function PushmeWidgetExportForm() {
	this.kind = 'iframe';
	this.style = 'default';
}

PushmeWidgetExportForm.prototype.styleClicked = function(style) {
	this.setStyle(style);
	this.render();
	this.updateFrames();
	return false;
}

PushmeWidgetExportForm.prototype.kindClicked = function(kind) {
	this.setKind(kind);
	this.render();
	this.updateFrames();
	return false;
}

PushmeWidgetExportForm.prototype.onFailure = function() {
	alert("Oops. Try again.");
}

PushmeWidgetExportForm.prototype.onSuccess = function(data, status) {
	eval("var obj="+data); // FIXME
	this.indeedUpdateFrames(obj.widgetHash);
}

PushmeWidgetExportForm.prototype.indeedUpdateFrames = function(hash) {
	$('#pushmeWidgetPreviewIframe').attr('src', '/z/widget/export/?hash='+hash+'&previewMode=1');
	$('#pushmeWidgetCodeIframe').attr('src', '/z/widget/code/?kind='+this.kind+'&colorScheme='+this.style);
}

PushmeWidgetExportForm.prototype.updateFrames = function() {
	$.ajax({
		'type':'POST',
		'url': '/z/ajax/widget/',
		'data':{
			'kind': this.kind,
			'colorScheme':this.style
		},

		'error' : this.onFailure.bind(this),
		'success':this.onSuccess.bind(this)
	});
}

PushmeWidgetExportForm.prototype.setHandlers = function() {
	// FIXME - to bind!! 
	$('#pushmeWidgetExportForm .kind').each(function(i) {
		$(this).bind('click', function() {pushmeWidgetExportForm.kindClicked(this.getAttribute('name'))})
	});
	$('#pushmeWidgetExportForm .style').each(function(i) {
		$(this).bind('click', function() {pushmeWidgetExportForm.styleClicked(this.getAttribute('name'))})
	});
}

PushmeWidgetExportForm.prototype.setKind = function(kind) {
	this.kind = kind;
	this.style='default';
}

PushmeWidgetExportForm.prototype.setStyle = function(style) {
	this.style = style;
}

PushmeWidgetExportForm.prototype.clearStyles = function() {
	$('#pushmeWidgetExportForm  #styles_iframe').hide();
	$('#pushmeWidgetExportForm  #styles_html').hide();
	$('#pushmeWidgetExportForm .active').each(function(i) {
		$(this).removeClass('active');
	});
}

PushmeWidgetExportForm.prototype.render = function() {
	this.clearStyles();
	$('#pushmeWidgetExportForm  #styles_'+this.kind).show();
	$('#pushmeWidgetExportForm .kind[name="'+this.kind+'"]').addClass('active');
	$('#pushmeWidgetExportForm .style[name="'+this.style+'"]').addClass('active');
}


PushmeCheckboxes = function() {
}

PushmeCheckboxes.prototype.isAnyOneEnabled = function() {
	var anyOne = false;
	$("#last_messages  dl  dt input").each(function(i,element){
		if (element.checked) {
			anyOne = true;
		}
	});

	return anyOne;
}

PushmeCheckboxes.prototype.tick = function() {
	this.enableDelete(this.isAnyOneEnabled());
}

PushmeCheckboxes.prototype.checkboxElements = function() {
	return $("#last_messages  dl  dt input");
}

PushmeCheckboxes.prototype.deleteLinkElement = function() {
	return $('#last_messages #bottom_links #delete_link');
}

PushmeCheckboxes.prototype.enableDelete = function(enable) {
	if (enable) {
		this.deleteLinkElement().addClass("active");
	} else {
		this.deleteLinkElement().removeClass("active");
	}
}

PushmeCheckboxes.prototype.selectAllClicked = function() {
	var iMetSomeone = false;
	this.checkboxElements().each(function(i,element){
		element.checked = "checked";
		iMetSomeone = true;
	});

	this.enableDelete(iMetSomeone);
	return false;
}

PushmeCheckboxes.prototype.deleteClicked = function() {
	var ids = [];
	if (this.deleteLinkElement().hasClass('active')) {
		this.checkboxElements().each(function(i, element){
			if (element.checked) {
				ids.push(element.name);
			}
		});

		$.ajax({
			'type':'POST',
			'url': '/z/ajax/delete/',
			'data':{
				'ids':ids.join(',')
			},
			'error' : this.onFailure.bind(this),
			'success':this.onSuccess.bind(this)
		});
	}
	return false;
}

PushmeCheckboxes.prototype.onFailure = function() {
	alert("Oops. Error happened. Try again later pls.")
}

PushmeCheckboxes.prototype.onSuccess = function(data, status) {
	document.location=document.location;
}




Uploader = function() {
	this.swfUpload = new SWFUpload({
		upload_url : "/z/attachment/upload/",
		flash_url : "/swf/swfupload.swf",
		//flash9_url : "/swf/swfupload_fp9.swf",
		file_size_limit : "15 MB",
		file_types : "*.jpg;*.png",
		file_types_description : "JPG Images; PNG Image",
		file_upload_limit : 8,

		file_queue_error_handler : this.fileUploadQueueError.bind(this),
		file_dialog_complete_handler : this.fileDialogComplete.bind(this),
		upload_error_handler : this.uploadError.bind(this),
		upload_success_handler : this.uploadSuccess.bind(this),
		upload_complete_handler : this.uploadComplete.bind(this),
		upload_start_handler: this.uploadStart.bind(this),

		button_placeholder_id : "push_form_upload_placeholder",
		button_width: 80,
		button_height: 18,
		button_text_top_padding: 2,
		button_text_left_padding: 18,

		button_image_url : '/img/plus_18x18.png',
		button_text : '<span class="button"><font color="#3399cc">Attach</font></span>',
		button_text_style : ".button { font-family: Helvetica, Arial, sans-serif; font-size: 13px; }",
		button_window_mode: SWFUpload.WINDOW_MODE.TRANSPARENT,
		button_cursor: SWFUpload.CURSOR.HAND
	});

	this.uploadWidth = 800;
	this.uploadHeight = 800;

	this.imagePlaceholdersCount=0;
	this.imagesInProgressCount=0; // either in process of deletion or upload

	this.filenamesToUpload = [];
}

Uploader.prototype.uploadedFilenames = function() {
	return this.filenamesToUpload;
}

Uploader.prototype.showError = function(errorMessage) {
	$('#push_form_upload_error').html(errorMessage).show();
}

Uploader.prototype.fileUploadQueueError = function(file, errorCode, message) {
	if (errorCode === SWFUpload.errorCode_QUEUE_LIMIT_EXCEEDED) {
		alert("You have attempted to queue too many files.");
		return;
	}

	switch (errorCode) {
		case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
			alert("This file is empty.")
			break;
		case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
			alert('This file is too big. You can add file up to 15 Mb.');
			break;
		case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:
			alert('This file is invalid. You can only add JPG and PNG files.');
			break;
		default:
			alert("Oops. Something wrong with the upload.");
			break;
	}

	// FIXME and if the error happens, then the loading indicator is still here. why?
}

Uploader.prototype.invokeStartResizedUpload = function() {
	this.swfUpload.startResizedUpload(
		null,
		this.uploadWidth,
		this.uploadHeight,
		SWFUpload.RESIZE_ENCODING.JPEG,
		75
	);
}

Uploader.prototype.fileDialogComplete = function(numFilesSelected, numFilesQueued) {
	this.addLoadingIndicator(numFilesSelected);
	try {
		if (numFilesQueued > 0) {
			this.invokeStartResizedUpload();
		}
	} catch (ex) {
		alert("Oops, there was an error queuing file for upload. Try again later?..");
	}
}

Uploader.prototype.uploadStart = function(file) {
	this.swfUpload.addPostParam("fn", file.name);
}

Uploader.prototype.onDeleteSuccess = function(data, textStatus, XMLHttpRequest) {
	$('div.upload-thumbnail').each(function(i, el) {
		var c = "upload-thumbnail-"+data.filename;
		if (el.id==c) {
			this.imagePlaceholdersCount--;
			$(el).parent().remove();
		}
	});

	// delete from upload queue
	var i=0;
	for(i=0;i<this.filenamesToUpload.length;i++) {
		if (this.filenamesToUpload[i]==data.filename) {
			this.filenamesToUpload.splice(i, 1);
			return;
		}
	}

	this.imagesInProgressCount--;
}

Uploader.prototype.onDeleteError = function() {
	alert("Oops, deletion failed. Try again later.");
	this.imagesInProgressCount--;
}

Uploader.prototype.deleteImage = function(event) {
	this.imagesInProgressCount++;
	$.ajax({
		url: '/z/attachment/delete-image/',
		dataType: 'json',
		data: {
			fn: event.data.filename
		},
		success: this.onDeleteSuccess.bind(this),
		error: this.onDeleteError.bind(this)
	});
}

Uploader.prototype.uploadSuccess = function(file, serverData) {
	this.imagesInProgressCount--;
	
	var obj = undefined;
	try {
		eval('var obj='+serverData);
	} catch(ex) {
		alert("Oops: cannot upload file. Try again later.");
	}

	if (obj) {
		this.addImageToList(obj);
	}
}

Uploader.prototype.addLoadingIndicator = function(count) {
	this.imagesInProgressCount+=count;

	var i=0;
	for (i=0;i<count;i++) {
		this.imagePlaceholdersCount++;
		var container = $('<div/>');
		container.addClass('send_message_image_container');
		var img = $('<img src="/img/loading.gif" class="push_form_uploading_indicator" alt="Loading.." />');
		img.addClass("upload-thumbnail");
		container.append(img);
		$('#push_form_upload_thumbnails').append(container);

		if (this.imagePlaceholdersCount%3==0) {
			$('#push_form_upload_thumbnails').append($('<br/>'));
		}
	}
}

Uploader.prototype.addImageToList = function(obj) {
	this.filenamesToUpload.push(obj.filename);
	
	var url='';
	if (obj['s3BucketName']) {
		url = 'http://'+obj['s3BucketName']+'.s3.amazonaws.com/'+obj.filename;
	} else {
		url = '/z/attachments/local/'+obj.filename;
	}
	
	var indicatorImg = $('img.push_form_uploading_indicator');
	if (indicatorImg.length>0) {
		var img = $(indicatorImg[0]);
		var place = img.parent();
		img.remove();

		var div = $('<div/>');
		div.addClass('thumbnail');
		div.addClass('upload-thumbnail');
		div.attr('id', "upload-thumbnail-"+obj.filename);
		div.css('background-image', 'url('+url+'.thumbnail.jpg)');

		img = $('<img/>');
		img.attr('alt', "Remove attachment");
		img.attr('title', "Remove attachment");
		img.attr('src', "/img/deletePicture.png");
		img.bind('click', {filename: obj.filename}, this.deleteImage.bind(this));
		div.append(img);
		place.append(div);
	}
}

Uploader.prototype.uploadComplete = function(file) {
	try {
		if (this.swfUpload.getStats().files_queued > 0) {
			this.invokeStartResizedUpload();
		} else {
			// all files complete
			// this.pushmeForm.enableSubmitButton(true);
		}
	} catch (ex) {
		alert("Oops: something wrong with the upload. Try again later?..");
	}
}

Uploader.prototype.uploadError = function(file, errorCode, message) {
	this.imagesInProgressCount--;
	switch (errorCode) {
		case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
			alert("Upload cancelled.");
			break;
		case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
			alert("Upload stopped.");
			break;
		case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:
			alert("Upload limit exceeded.");
			break;
		case SWFUpload.UPLOAD_ERROR.IO_ERROR:
			alert("Cannot upload file.");
			break;
		default:
			alert("Oops, upload error: "+message);
			break;
	}
}

PushmeMessages = function () {
}

PushmeMessages.prototype.showOlder = function(lastShownMessageId) {
	$('#old_messages_loading_in_progress').css('visibility','visible');
	$('#older_messages').load(
		'/z/index/older-messages/?lastShownMessageId='+lastShownMessageId,
		function(responseText, textStatus, xhr){
			if (xhr.status == 200) {
				$('#show_older_messages').hide();
			} else {
				$('#old_messages_loading_in_progress').css('visibility','hidden');
			}
		}
	);
	return false;
}



