
<style type="text/css">
body { font-family:Tahoma, Verdana, Arial, Sans-Serif; }
</style>


JFIELD = {
	unique: 0, // counter for making elements unique
	imported_fcode_script: 0,
	imported_ajaxupload_script: 0,
	is_dirty: function() {
		var _ret = 0;
		$('.jfield').each(function() {
			if (this.P.dirty == 1) {
				_ret = 1;
				return false;
			}
		});
		return _ret;
	},

	counter_change: 0,
	notification_count: 0,
	notify: function(msg,color) {
		if (typeof msg == 'undefined') { var msg = 'Ahoy!'; }
		if (typeof color == 'undefined') { var color = '#69e'; }
		$('#jfieldnotifications_notifications').append('<div id="notification-' + JFIELD.notification_count + '" class="notification" style="background:' + color + '; display:none; position:relative; font-weight:bold; color:#000020; cursor:pointer; border-top:1px solid #5a5a5a; font-size:0.86em;"><div style="padding:5px;">' + msg + '</div></div>');
		$('#notification-' + JFIELD.notification_count).click(function() {
			$(this).fadeOut(360);
			setTimeout("$('#" + this.id + "').remove()",1000);
			return false;
		});
		$('#notification-' + JFIELD.notification_count).slideDown(360);
		JFIELD.notification_count = JFIELD.notification_count + 1;
	},
	unnotify: function(msg) {
		if (typeof msg == 'undefined') { var msg = 'Ahoy!'; }
		$('#jfieldnotifications_notifications').children('.notification').each(function() {
			if ($(this).text() == msg) {
				$(this).slideUp(360);
				setTimeout("$('#" + this.id + "').remove()",1000);
				return false;
			}
		});
	},
	notice_change: function() { // make it look edited
		if (JFIELD.counter_change == 0) {
			
			JFIELD.notify('(changes made)','#fc5');
			JFIELD.counter_change = JFIELD.counter_change + 1;
			 document.title = '* ' + document.title;
			return true;
		}
		return false;
	},
	notice_unchange: function() { // make it look saved
		if (JFIELD.counter_change > 0) {
			
			JFIELD.unnotify('(changes made)');
			JFIELD.counter_change = 0;
			 document.title = document.title.replace('* ','');
			return true;
		}
		return false;
	},
	notice_saving: function() {
		JFIELD.notify('Saving...','#fff999');
		return true;
	},
	notice_saved: function() {
		JFIELD.notice_unchange();
		JFIELD.unnotify('Saving...');
		JFIELD.notify('Saved.','#69e');
		setTimeout("JFIELD.unnotify('Saved.')",2000);
		return true;
	},
	notice_run: function() {
		var c = true;
		if (JFIELD.counter_change > 0) {
			var c = confirm('Really run before saving changes?');
		}
		if (c == true) {
			JFIELD.notify('Run (uses popup)','#f5f5f5');
			setTimeout("JFIELD.unnotify('Run (uses popup)')",2000);
		}
		return c;
	}
}

function jfield(el) { // where el is a div element output by tag.jfield

	// make el id unique
	el.id = el.id + '-' + JFIELD.unique;
	 JFIELD.unique = JFIELD.unique + 1;

  // PROPERTIES
	var _split = el.id.split('|');
	 var _title = _split[0];
	  _jstr = _split[0].replace('/','').replace(/[\/\.]/g,'-');
	   var _jstr_split = _jstr.split('-');
	  _settings = _split[1];
	   var _settings_split = _settings.split('-');
	el.jtitle = _title; // internally, i think of this as the "title" - it's the jParse string
	if (typeof el.title == 'string' && el.title.length > 0) {
		// do nothing: use supplied title
	}
	else {
		// use _jtitle as element title
		el.title = el.jtitle;
	}
	el.P = {
		init: 0,
		val: '',
		 dirty: 0,
		 mode: 'view',
		otype: _jstr_split[0],
		idstr: _jstr_split[1],
		fname: _jstr_split[2],
		type: _settings_split[0],
		  input_type: '',
		  src: '',
		readonly: _settings_split[1],
		update: _settings_split[2]
	}

	if (el.P.readonly == 'yes' || el.P.update !== 'yes') { return false; }

	// may need to import certain scripts...
	  if (el.P.type == 'code' && JFIELD.imported_fcode_script == 0 && typeof fcode == 'undefined') {
		$.getScript('http://fentriss.net/fcode.js');
		JFIELD.imported_fcode_script = 1;
	  }
	  else if (el.P.type == 'file' && JFIELD.imported_ajaxupload_script == 0 && typeof AjaxUpload == 'undefined') {
		$.getScript('http://fentriss.net/ajaxupload.js');
		JFIELD.imported_ajaxupload_script = 1;
	  }

  // MARKUP
	el.zone_view_blocker = null; // prevents user from hovering/clicking zone_view during edit mode
		$(el).append('<div class="jfield_view_blocker" style="z-index:2; position:absolute; display:none; width:100%; height:100%; top:0px; left:0px;"></div>');
		el.zone_view_blocker = $(el).find('.jfield_view_blocker')[0];
	el.zone_view = $(el).find('.jfield_view')[0];
		$(el.zone_view).css('z-index','1');
		$(el.zone_view).css('cursor','pointer');
		//$(el.zone_view).css('padding','5px');
		var _testMinHeight = $(el.zone_view).css('min-height');
		if ( _testMinHeight == '' || _testMinHeight == '0px' ) {
			$(el.zone_view).css('min-height','1.12em');
		}
		$(el.zone_view).hover(
			function() { $(this).css('background','#69e'); $(this).css('color','#000020'); $(this).find('img').css('opacity','0.6'); },
			function() { $(this).css('background',''); $(this).css('color',''); $(this).find('img').css('opacity','1'); }
		);
	el.zone_edit = $(el).find('.jfield_edit')[0];
		$(el.zone_edit).css('z-index','3');
		$(el.zone_edit).css('position','absolute');
		$(el.zone_edit).css('left','1em');
		$(el.zone_edit).css('top','1em');
	  el.zone_edit_head = null; // the div that will contain this field's title, save btn and close btn
	    el.btn_save = null;
	    el.btn_cancel = null;
	  el.zone_edit_body = null;
	    el.zone_edit_input = null; // the input/textarea/select/etc. that will contain an interesting value
	  el.zone_edit_foot = null; // the div that will contain this field's status info
		var _head_html = '<div class="jfield_edit_head" style="position:relative; padding:5px; background:#69e; color:#000020; border:1px solid #000020;"><small>\
		  <b>' + el.title + '</b>\
		  &nbsp; &nbsp; &nbsp; \
		  <span style="">\
		    <a class="jfield_btn_save" style="color:#000020; background:#69e; padding:3px;" href="#" onclick="return false;" class="save_btn">Save</a>\
		     &nbsp; \
		    <a class="jfield_btn_cancel" style="color:#000020;" href="#" onclick="return false;">Exit</a>\
		  </span>\
		</small></div>';
		var _body_html = '<div class="jfield_edit_body" style="margin-left:1.2em; margin-top:-1px; position:relative; padding:5px; padding-top:2px; background:#69e; border-style:solid; border-color:#000020; border-width:0px 1px 1px 1px;">';
		  // what input goes in the body?  that depends on the field type.
		  var _input_html = '';  var _style = 'display:block; width:99%; font-size:1em; color:#f5f5f5; background:#000020; border:1px solid #b7b7b7; padding:2px;';
		  	if (el.P.type == 'file') {
		  		var _btn_txt = 'New File...';
		  		  if (el.P.update == 'no') {
		  			var _btn_txt = '(cannot update)';
		  		  }
		  		var _input_html = '<button id="input|' + el.id + '" class="jfield_edit_input" style="' + _style + ' min-width:10em;">' + _btn_txt + '</button>';
		  		  el.P.input_type = 'file';
		  		  el.P.src = $(el.zone_view).find('img')[0].src;
		  	}
			else if (el.P.type == 'longtext' || el.P.type == 'code') {
				var _input_html = '<textarea id="input|' + el.id + '" wrap="off" spellcheck="false" class="jfield_edit_input" style="' + _style + ' min-width:28em; height:99%; min-height:7em; font-family:Andale Mono, Courier New, Courer, Monspace !important;"></textarea>';
		  		  el.P.input_type = 'textarea';
			}
			else { // default: shorttext
				var _input_html = '<input id="input|' + el.id + '" class="jfield_edit_input" type="text" style="' + _style + ' min-width:10em;">';
		  		  el.P.input_type = 'textbox';
			}
		var _body_html = _body_html + _input_html + '</div>';
	  $(el.zone_edit).html(_head_html + _body_html);
		el.zone_edit_head = $(el.zone_edit).find('.jfield_edit_head')[0];
		  el.btn_save = $(el.zone_edit_head).find('.jfield_btn_save')[0];
		  el.btn_cancel = $(el.zone_edit_head).find('.jfield_btn_cancel')[0];
		el.zone_edit_body = $(el.zone_edit).find('.jfield_edit_body')[0];
		  el.zone_edit_input = $(el.zone_edit_body).find('.jfield_edit_input')[0];
	// each significant element refers to the jfield el by storing it in "that"
	  el.zone_view.that = el; el.zone_view_blocker.that = el; el.zone_edit.that = el; el.zone_edit_head.that = el; el.btn_save.that = el; el.btn_cancel.that = el; el.zone_edit_body.that = el; el.zone_edit_input.that = el;
	// hide save btn if no update
	  if (el.P.update == 'no' || el.P.type == 'file') {
		$(el.btn_save).hide();
	  }

  // METHODS
	el.get_val = function() { // get val from view, set edit
		if (this.P.type == 'file') { return false; }
		var _val = $(this.zone_view).text();
		this.P.val = _val;
		$(this.zone_edit_input).val(this.P.val);
	}
	el.set_val = function(use_new_value) { // get val from edit, set view
		// notice that value is not updated only for this jfield element, but also for jfield elements with similar titles (that is, with same exact db addresses)
		var _val = this.P.val;
		  if (use_new_value == 1) {
			var _val = $(this.zone_edit_input).val();
			this.P.val = _val;
		  }
		var _title = this.jtitle;
		$('.jfield').each(function() {
		  if (this.jtitle == _title) {
			if (this.P.type == 'file') {
				// simply randomize the image source, causing a refresh
				var _rando = Math.random();
				var _new_src = this.P.src + '&noCache=1&rando=' + _rando;
				$(this.zone_view).find('img').attr('src',_new_src);
			}
			else {
				$(this.zone_view).text(_val);
				  $(this.zone_view).html($(this.zone_view).html().replace(/\n/g,'\n<br>'));
				   $(this.zone_view).html($(this.zone_view).html().replace(/\t/g,'\t<span style="display:inline-block; width:4em;"></span>'));
			}
		  }
		});
	}
	el.edit_mode = function() {
		this.P.mode = 'edit';
		this.get_val();
		$(this.zone_view).css('opacity','0.3');
		 $(this.zone_view_blocker).show();
		$(this.zone_edit).show();
		this.reposition();
		try {
			if (this.P.input_type == 'textbox') {
				$(this.zone_edit_input).select();
			}
			else {
				$(this.zone_edit_input).focus();
			}
		} catch(err) { }
		// certain fields require an init phase
		  if (this.P.init == 0) {
			if (this.P.type == 'file' && this.P.update == 'yes') {
				el.ajax_upload = new AjaxUpload(el.zone_edit_input.id, {
					action:'http://' + document.domain + '/?&siteformat=xml',
					name:'1_file',
					data: {
						"1_posttype": 'UPDATE',
						"1_orb": el.P.otype,
						"1_where": this.where_clause()
					},
					autoSubmit:true,
					responseType:'text/xml',
					onChange: function() {
						this.that.save();
					},
					onSubmit: function() {
						// :)
					},
					onComplete: function(file,response) {
						this.that.save2();
					}
				});
				el.ajax_upload.that = el;
			}
			else if (this.P.type == 'code') {
				$(this.zone_edit).css('position','fixed');
				$(document.body).append(this.zone_edit);
				fcode(this.zone_edit_input,1);
			}
			this.P.init = 1;
		  }
	}
	el.view_mode = function(use_new_value) {
		this.P.mode = 'view';
		this.set_val(use_new_value);
		$(this.zone_edit).hide();
		$(this.zone_view).css('opacity','1');
		 $(this.zone_view_blocker).hide();
	}
	el.dirty = function() {
		if (this.P.dirty == 1 || this.P.mode !== 'edit') { return false; }
		if ($(this.zone_edit_input).val() !== this.P.val) {
			this.P.dirty = 1;
			$(this.zone_edit_head).css('background','#fc5');
			$(this.zone_edit_body).css('background','#fc5');
			 JFIELD.notice_change();
			$(this.btn_cancel).html('Cancel');
		}
	}
	el.clean = function() {
		this.P.dirty = 0;
		$(this.zone_edit_head).css('background','#69e');
		$(this.zone_edit_body).css('background','#69e');
		$(this.btn_cancel).html('Close');
	}
	el.save = function() {
		if (this.P.update == 'no') {
			this.save2('bypass');
		}
		else if (this.P.type == 'file') {
			JFIELD.notice_saving();
		}
		else {
			var _Q = new Object();
			  _Q['1_' + this.P.fname] = $(this.zone_edit_input).val();
			  _Q['1_posttype'] = 'UPDATE';
			  _Q['1_orb'] = this.P.otype;
			  _Q['1_where'] = this.where_clause();
			$.post('http://' + document.domain + '/?&siteformat=xml&elId=' + this.id, _Q, function(data) {
				var splitz = this.url.split('=');
				var elId = splitz[splitz.length-1];
				document.getElementById(elId).save2(data);
			});
			 JFIELD.notice_saving();
		}
	}
	  el.save2 = function(data) {
		if (typeof data == 'string' && data == 'bypass') {
			// fake save
			this.view_mode();
			this.clean();
			 JFIELD.unnotify('(changes made)');
			/* callback */
			if (typeof after_jfield_save !== 'undefined') {
				after_jfield_save(el,1);
			}
			return false;
		}
		var status = jQuery.trim($(data).find('post_status').text());
		var message = jQuery.trim($(data).find('post_message').text());
		if (status.toString() == '2') {
			// hmm...
			var errCode = jQuery.trim(message.split(':')[0]);
			if (errCode.toString() == '2011') {
				alert('Cannot save.  Did you log out?');
			}
			else {
				alert('That unique title is already in use!  Please try another.');
			}
			 JFIELD.unnotify('Saving...');
			/* callback */
			if (typeof after_jfield_save !== 'undefined') {
				after_jfield_save(el,0);
			}
		}
		else {
			// yay!
			if (this.P.type == 'code') {
				// code shouldn't go away unless you click "close"
				this.set_val(1);
			}
			else {
				// most inputs should disappear as soon as you save.
				this.view_mode(1);
			}
			this.clean();
			 JFIELD.notice_saved();
			/* callback */
			if (typeof after_jfield_save !== 'undefined') {
				after_jfield_save(el,1);
			}
		}
	  }
	el.cancel = function() {
		if (this.P.dirty == 1 && this.P.update == 'yes') {
			var c = confirm('Discard changes?');
			if (!c) { return false; }
		}
		this.view_mode();
		this.clean();
		 JFIELD.notice_unchange();
	}
	el.reposition = function(is_recur) {
		if (this.P.mode !== 'edit') { return false; }
		if (this.P.type == 'code') {
			// hog the screen!
			$(this.zone_edit).css('position','fixed');
			$(this.zone_edit).css('left','3%');
			$(this.zone_edit).css('top','2%');
			$(this.zone_edit).css('width','94%');
			$(this.zone_edit).css('height','94%');
			$(this.zone_edit).css('z-index','1000');
			 $(this.zone_edit_body).css('height','94%');
		}
		else {
			// use fixed (to escape overflow:hidden situations), but make it look like normal
			var _screen_x_max = $(window).width() - $(this.zone_edit).width() - 24;
			  var _screen_y_max = $(window).height() - $(this.zone_edit).height() - 24;
			var _x = $(this).offset().left;
			  var _x = _x - $(window).scrollLeft() + 16;
			var _y = $(this).offset().top;
			  var _y = _y - $(window).scrollTop() + 16;
			if (_x > _screen_x_max) {
				var _x = _screen_x_max;
			}
			if (_y > _screen_y_max) {
				var _y = _screen_y_max;
			}
			$(this.zone_edit).css('position','fixed');
			$(this.zone_edit).css('left',_x + 'px');
			$(this.zone_edit).css('top',_y + 'px');
			$(this.zone_edit).css('z-index','1000');
		}
		if (is_recur == 1) {
			setTimeout("document.getElementById('" + this.id + "').reposition()",1000);
		}
	}
	el.where_clause = function() {
		// a silly little function to produce the correct where clause, because different clauses are required depending on the idstr (gutitle or id num)
		  if (!this.P.idstr.toString().match(/[0-9]/)) {
			// idstr is a gutitle
			  var _ret = this.P.otype + '.gutitle = \'' + this.P.idstr + '\'';
		  }
		  else {
			// idstr is an id number
			  var _ret = this.P.otype + '.id = ' + this.P.idstr;
		  }
		  return _ret;
	}

  // ASSIGNMENTS
	// click the view zone to enter edit mode
	  $(el.zone_view).click(function() {
		var el = this.that;
		el.edit_mode();
		return false;
	  });
		
	// check field for changes while you edit
	if (el.P.type !== 'file') {
	  $(el.zone_edit_input).bind('keyup change blur',function() {
		var el = this.that;
		el.dirty();
	  });
	}
	// click the save btn to save
	  $(el.btn_save).click(function() {
		var el = this.that;
		el.save();
		return false;
	  });
	  if (el.P.type !== 'file') {
		// ctrl+S is always save, ctrl+R is always run, ctrl+W is always cancel
		  $(el.zone_edit_input).bind('keydown', function(e) {
			if (e.ctrlKey) { // ctrl
				if (e.keyCode == 83) { // ctrl+s: save
					var el = this.that;
					el.save();
					return false;
				}
				else if (e.keyCode == 82) { // ctrl+r: run
					var el = this.that;
					JFIELD.notice_run();
					setTimeout("window.open('http://" + document.domain + "/run:/" + el.P.otype + "-" + el.P.idstr + "')",1000);
					return false;
				}
				else if (e.keyCode == 87) { // ctrl+w: cancel
					var el = this.that;
					setTimeout("document.getElementById('" + el.id + "').cancel()",20);
					return false;
				}
			}
		  });
		// in non-textarea elements, enter key also saves
		  if (el.P.input_type == 'textbox') {
			$(el.zone_edit_input).bind('keydown', function(e) {
				if (e.keyCode == 13) { // enter: save
					var el = this.that;
					if (el.P.fname == 'gutitle' || el.P.type == 'gutitle') {
						// for gutitle fields, first make sure there's no ending underscore
						var _v = $(this).val();
						if (_v.length > 0 && _v.lastIndexOf('_') == _v.length-1) {
							$(this).val(_v.substr(0,_v.length-1));
						}
					}
					el.save();
					return false;
				}
			});
		  }
		
	  }
	// click the cancel btn to revert to view mode
	  $(el.btn_cancel).click(function() {
		var el = this.that;
		el.cancel();
		return false;
	  });
	if (el.P.fname == 'gutitle' || el.P.type == 'gutitle') {
		// force gutitle format on gutitle fields
		$(el.zone_edit_input).bind('keyup', function(e) {
			var _orig = $(this).val();
			var _v = jQuery.trim($(this).val()).toLowerCase();
			if (_v.length == 0) {
				return true;
			}
			var _v = _v.replace(/[^a-z_]/gi,'');
			var _v = _v.replace(/(_)+/g,'_');
			if (_v.indexOf('_') == 0) {
				var _v = _v.replace('_','');
			}
			if (_v !== _orig) {
				$(this).val(_v);
			}
		});
		$(el.zone_edit_input).bind('blur change', function() {
			var _v = $(this).val();
			if (_v.length > 0 && _v.lastIndexOf('_') == _v.length-1) {
				$(this).val(_v.substr(0,_v.length-1));
			}
		});
	}

}

// add notifications container
$(document.body).append('<div id="jfieldnotifications_notifications_container" style="position:fixed; z-index:1001; right:32px; bottom:0px; overflow:visible;"><div id="jfieldnotifications_notifications" style="width:180px; position:relative;"></div></div>');
// activate jfields
$('.jfield').each(function() {
	jfield(this);
});

window.onbeforeunload = function() {
	if (JFIELD.is_dirty() == 1) {
		if (BROWSER_TYPE == 'IE') {
			return '';
		}
		else {
			return false;
		}
	}
}; 
