var EditField = Class.create({
	initialize: function (editContainer) {
		this.container = editContainer;
		
		// get entity/field info
		this.entityClass = $F(this.getElementByClassName("edit_field_entity_class"));
		this.entityField = $F(this.getElementByClassName("edit_field_entity_field"));
		this.entityId    = $F(this.getElementByClassName("edit_field_entity_id"));
		this.isDraft     = $F(this.getElementByClassName("edit_field_is_draft")) ? 1 : 0;
		this.isPassword  = $F(this.getElementByClassName("edit_field_is_password")) == 1 ? true : false;
		this.isCheckbox  = $F(this.getElementByClassName("edit_field_is_checkbox")) == 1 ? true : false;
		
		this.canSave = true;
		
		if (! this.entityClass || ! this.entityField || ! this.entityId) {
			if (this.getElementByClassName("edit_field_button"))
				this.getElementByClassName("edit_field_button").hide();
				
			return;
		}
		
		this.registerEventHandlers();
	},
	
	showValue: function () {
		var valueLabel = this.getElementByClassName("edit_field_value");
		if (valueLabel)
			valueLabel.show();
	},
	hideValue: function () {
		var valueLabel = this.getElementByClassName("edit_field_value");
		if (valueLabel)
			valueLabel.hide();
	},
	setValue: function (val) {
		var valueLabel = this.getElementByClassName("edit_field_value");
		
		if (this.isPassword) {
		    val = "********";
		}
		if (this.isCheckbox) {
		    val = val ? "Yes" : "No";
		}
		
		if (valueLabel)
			valueLabel.update(val);
	},
	
	showEditField: function () {
		// hide display and button
		this.hideValue();
		
		var editButton = this.getElementByClassName("edit_field_button");
		if (editButton)
		    editButton.hide();
		
		var valueField = this.getElementByClassName("edit_field_value_field");
		if (valueField && ! this.isPassword) {
			this.getEditField().value = $F(valueField);
		}
		
		// show edit field controls
		var editControls = this.getElementByClassName("edit_field_controls");
		var editField = this.getEditField();
		editControls.show();
		
		this.getEditField().enable();
		this.getEditField().activate();
		
		return false;
	},
	
	hideEditField: function () {
		var editControls = this.getElementByClassName("edit_field_controls");
		editControls.hide();
		
		this.showValue();
		
		var editButton = this.getElementByClassName("edit_field_button");
		if (editButton)
		    editButton.show();
	},
	
	saveEdit: function () {
		// TODO: show progress indicator
		
		// get new value
		var newValue = $F(this.getEditField());
		var valueField = this.getElementByClassName("edit_field_value_field");
		
		if (this.isCheckbox) {
		    newValue = newValue ? 1 : 0;
		}
		
                valueField.value = newValue;
		
		// dont set empty passwords
                if (this.isPassword) {
		    if (! newValue) {
		        // can't set new empty password
		        this.cancelEdit();
		        return;
		    }

                    if (this.entityField != 'twitterpassword')
                        newValue = SHA1(newValue);
		}
		
		this.getEditField().disable();
		
		// do request
		var self = this;
		var params = {
			"id": this.entityId
		};
		params["" + this.entityField] = newValue;
		
		var pw2 = this.getElementByClassName("password_edit_2");
		if (pw2)
		    pw2.disable();
		
		doRest(
			this.entityClass + "/" + this.entityId + "",   // url (/class/id = REST object handler (update/delete))
			this.editSavedCallback.bind(this),             // success cb
			params,                                        // request data
			"put",                                         // method (PUT to /class/id = update)
			this.cancelEdit.bind(this)                     // exception handler
		);
	},
	
	editSavedCallback: function (transport) {
	    // reenable pw2 field if exists (this is a password field)
	    var pw2 = this.getElementByClassName("password_edit_2");
	    if (pw2) pw2.enable();
	    
	    // get response
	    var res = transport.responseJSON;
    	if (! res) return this.cancelEdit();
    	
    	// check success
    	if (! res.success || res.success == "false") {
    	    var messages = res.messages;
    	    if (messages && messages.length) {
    	        alert("Sorry, there was a problem saving your changes:\n\n" + 
    	            messages.join("\n"));
    	    }
    	    
    	    return this.cancelEdit();
    	}
    	
	    // find the field containing the value, update it appropriately
		var editField = this.getEditField();
		if (! editField) return this.hideEditField();

		if (editField.tagName.toUpperCase() == "SELECT") {
			try {
				this.setValue(editField.options[editField.selectedIndex].text.escapeHTML())
			} catch (e) { alert(e) }
		} else if (this.isCheckbox) {
		    this.setValue($F(editField) ? 1 : 0);
		} else {
			this.setValue($F(editField).escapeHTML());
			// keep labels synch'd...
			if (this.entityField == "name") {
				// update RTQ title
				var valueLabel = document.getElementById("rtq_title_" + this.entityId);
				if (valueLabel)
					valueLabel.update($F(editField).escapeHTML());	
				// update Shadowbox
				var valueLabel = document.getElementById("sb-title-inner");
				if (valueLabel)
					valueLabel.update("Settings For " + $F(editField).escapeHTML());					
			}					
		}
		
		this.hideEditField();
	},
	
	cancelEdit: function () {
		this.hideEditField();
	},
	
	handleKeyPress: function (event) {
		if (! checkEnter(event)) return;
		
		// if this is part of a form, we don't want to save just this individual element on enter
		if (this.canSaveOnEnterKey)
		    this.saveEdit();
	},
	
	registerEventHandlers: function () {
		var editField = this.getEditField();
		if (! editField) return;

		var showFunc = function (event) {
		    this.showEditField();
		    event.stop();
	    };
		
		// add event listeners on the parent container that can be triggered
		var editContainer = this.container;
		if (editContainer) {
		    editContainer.observe('lexy:showEdit', showFunc.bind(this));
		    editContainer.observe('lexy:saveEdit', this.saveEdit.bind(this));
		    editContainer.observe('lexy:cancelEdit', this.cancelEdit.bind(this));
		    
		    editContainer.validateForm = this.isPassword ? 
		        this.validatePasswordForm.bind(this) : 
		        this.validateForm.bind(this);
        }
        		
		var editButton = this.getElementByClassName("edit_field_button");
		if (editButton)
		    editButton.observe('click', showFunc.bind(this));
		
		var saveButton = this.getElementByClassName("edit_field_save_button");
		var cancelButton = this.getElementByClassName("edit_field_cancel_button");
		
		if (cancelButton)
		    cancelButton.observe('click', this.cancelEdit.bind(this));
		
		if (saveButton) {
		    saveButton.observe('click', this.saveEdit.bind(this));
		    editField.observe('keypress', this.handleKeyPress.bind(this));
		    this.canSaveOnEnterKey = true;
		} else {
		    this.canSaveOnEnterKey = false;
		}
		
	    if (this.isPassword && this.getElementByClassName('password_edit_2')) {
		    // bind to second password field as well
		    this.getElementByClassName('password_edit_2').observe('keypress', this.handleKeyPress.bind(this));
		}
	},
	
	getEditField: function () {
		return this.getElementByClassName("edit_field_input");
	},
	
	getElementByClassName: function (cname) {
		return this.container.getElementsByClassName(cname)[0];
	},
	
	validatePasswordForm: function () {
	    var pw1 = this.getElementByClassName("password_edit_1");
	    var pw2 = this.getElementByClassName("password_edit_2");
	    
	    if (! pw1 || ! pw2) {
	        return true;
	        console.log("did not find pw1 or 2 on password field");
            // :(
            // ....
	    } else {
	        var p1 = $F(pw1);
	        var p2 = $F(pw2);
	        
	        if (! p1 && ! p2)
	            return true;
            
	        if (! p1) {
	            alert("New password cannot be blank");
	            return false;
	        }
	        
	        if (! p2) {
	            alert("Please retype your new password");
	            return false;
	        }
	        
	        if (p1 != p2) {
	            alert("Oops, your passwords don't match.  Make it easier on Lexy and please re-enter both your password and the confirmation.");
	            return false;
	        }

                if (this.entityField != 'twitterpassword')
	           newValue = SHA1(p1);
	    }
	    
	    return true;
	},
	
	// validate the contents of this form, override
	// this gets attached to the container, not the editfield, so validation
	// can check multiple fields
	validateForm: function () {
	    return true;
	}
});


//// onload
document.observe("dom:loaded", function () {
	//if (editFieldsDisabled) return;
	
	var editContainers = $$(".edit_field_container");
	
	editContainers.each(function (ec) { new EditField(ec) });
});

function detectShadowbox(parent) {
	try {
		if (Shadowbox.isActive()) 
			return $('sb-content').firstChild;
	} catch (e) {}
	return parent;
}

function hideAllEditFields() {
	var editContainers = $$(".edit_field_container");
	editContainers.each(function (ec) { ec.showFunc(); });
	
	$("preview_mode_button").hide();
	$("edit_mode_button").show();
}
function showAllEditFields() {
	var editContainers = $$(".edit_field_container");
	editContainers.each(function (ec) { ec.showFunc(); });
	
	$("preview_mode_button").show();
	$("edit_mode_button").hide();
}

function validateAllEditFields(parent) {
    var editContainers = $A(parent.getElementsByClassName("edit_field_container"));
	
	// do validations first
	var unValidated = editContainers.map(function (e) { return ! e.validateForm(); }).any();
	if (unValidated) {
	    return false;
	}
	
	return true;
}

function activateAllEditFields(parent) {
	parent = detectShadowbox(parent);
	var editContainers = $A(parent.getElementsByClassName("edit_field_container"));
	editContainers.each(function (ec) { ec.fire('lexy:showEdit'); });
	$('actions_for_edit_fields_' + parent.id).show();
}

function saveAllEditFields(parent) {
	parent = detectShadowbox(parent);
	var editContainers = $A(parent.getElementsByClassName("edit_field_container"));
	
	// validate everything first
	if (! validateAllEditFields(parent)) {
	    return;
	}
	
	editContainers.each(function (ec) { ec.fire('lexy:saveEdit'); });
	$('actions_for_edit_fields_' + parent.id).hide();
}
function cancelAllEditFields(parent) {
	parent = detectShadowbox(parent);
	var editContainers = $A(parent.getElementsByClassName("edit_field_container"));
	editContainers.each(function (ec) { ec.fire('lexy:cancelEdit'); });
	$('actions_for_edit_fields_' + parent.id).hide();
}

function getUploadLink(evt) {
	Event.extend(evt);
	var link = Event.findElement(evt, "a");
	return link;
}

function getUploadForm(evt) {
	Event.extend(evt);
	
	var link = getUploadLink(evt);
	if (! link) return;
	
	var parent = link.parentNode;
	parent = detectShadowbox(parent);
	if (! parent) return;
	
	var uploadForm = parent.getElementsByClassName("edit_image_upload_form")[0];
	if (! uploadForm) return;
	
	return uploadForm;
}

function showImageUpload(evt) {
	var link = getUploadLink(evt);
	var uploadForm = getUploadForm(evt);
	
	if (! link || ! uploadForm) return;
	
	link.hide();
	uploadForm.show();
}

function hideImageUpload(id) {
	var link = $("edit_image_link_" + id);
	var uploadForm = $("edit_image_upload_form_" + id);
	
	if (! link || ! uploadForm) return;
	
	link.show();
	uploadForm.hide();
}



///// FOR EDIT PASSWORD
function SHA1 (msg) { 
	function rotate_left(n,s) {
		var t4 = ( n<<s ) | (n>>>(32-s));
		return t4;
	};
 
	function lsb_hex(val) {
		var str="";
		var i;
		var vh;
		var vl;
 
		for( i=0; i<=6; i+=2 ) {
			vh = (val>>>(i*4+4))&0x0f;
			vl = (val>>>(i*4))&0x0f;
			str += vh.toString(16) + vl.toString(16);
		}
		return str;
	};
 
	function cvt_hex(val) {
		var str="";
		var i;
		var v;
 
		for( i=7; i>=0; i-- ) {
			v = (val>>>(i*4))&0x0f;
			str += v.toString(16);
		}
		return str;
	};
 
 
	function Utf8Encode(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;
	};
 
	var blockstart;
	var i, j;
	var W = new Array(80);
	var H0 = 0x67452301;
	var H1 = 0xEFCDAB89;
	var H2 = 0x98BADCFE;
	var H3 = 0x10325476;
	var H4 = 0xC3D2E1F0;
	var A, B, C, D, E;
	var temp;
 
	msg = Utf8Encode(msg);
 
	var msg_len = msg.length;
 
	var word_array = new Array();
	for( i=0; i<msg_len-3; i+=4 ) {
		j = msg.charCodeAt(i)<<24 | msg.charCodeAt(i+1)<<16 |
		msg.charCodeAt(i+2)<<8 | msg.charCodeAt(i+3);
		word_array.push( j );
	}
 
	switch( msg_len % 4 ) {
		case 0:
			i = 0x080000000;
		break;
		case 1:
			i = msg.charCodeAt(msg_len-1)<<24 | 0x0800000;
		break;
 
		case 2:
			i = msg.charCodeAt(msg_len-2)<<24 | msg.charCodeAt(msg_len-1)<<16 | 0x08000;
		break;
 
		case 3:
			i = msg.charCodeAt(msg_len-3)<<24 | msg.charCodeAt(msg_len-2)<<16 | msg.charCodeAt(msg_len-1)<<8	| 0x80;
		break;
	}
 
	word_array.push( i );
 
	while( (word_array.length % 16) != 14 ) word_array.push( 0 );
 
	word_array.push( msg_len>>>29 );
	word_array.push( (msg_len<<3)&0x0ffffffff );
 
 
	for ( blockstart=0; blockstart<word_array.length; blockstart+=16 ) {
 
		for( i=0; i<16; i++ ) W[i] = word_array[blockstart+i];
		for( i=16; i<=79; i++ ) W[i] = rotate_left(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
 
		A = H0;
		B = H1;
		C = H2;
		D = H3;
		E = H4;
 
		for( i= 0; i<=19; i++ ) {
			temp = (rotate_left(A,5) + ((B&C) | (~B&D)) + E + W[i] + 0x5A827999) & 0x0ffffffff;
			E = D;
			D = C;
			C = rotate_left(B,30);
			B = A;
			A = temp;
		}
 
		for( i=20; i<=39; i++ ) {
			temp = (rotate_left(A,5) + (B ^ C ^ D) + E + W[i] + 0x6ED9EBA1) & 0x0ffffffff;
			E = D;
			D = C;
			C = rotate_left(B,30);
			B = A;
			A = temp;
		}
 
		for( i=40; i<=59; i++ ) {
			temp = (rotate_left(A,5) + ((B&C) | (B&D) | (C&D)) + E + W[i] + 0x8F1BBCDC) & 0x0ffffffff;
			E = D;
			D = C;
			C = rotate_left(B,30);
			B = A;
			A = temp;
		}
 
		for( i=60; i<=79; i++ ) {
			temp = (rotate_left(A,5) + (B ^ C ^ D) + E + W[i] + 0xCA62C1D6) & 0x0ffffffff;
			E = D;
			D = C;
			C = rotate_left(B,30);
			B = A;
			A = temp;
		}
 
		H0 = (H0 + A) & 0x0ffffffff;
		H1 = (H1 + B) & 0x0ffffffff;
		H2 = (H2 + C) & 0x0ffffffff;
		H3 = (H3 + D) & 0x0ffffffff;
		H4 = (H4 + E) & 0x0ffffffff;
	}
	var temp = cvt_hex(H0) + cvt_hex(H1) + cvt_hex(H2) + cvt_hex(H3) + cvt_hex(H4);
	return temp.toLowerCase();
}