/*
    jlog (JavaScript Log Observation Glasses)
    version 1.0 Copyright (C) 2006-2007 Tagata Akira

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
    published by the Free Software Foundation; either version 2 of the
    License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
    02110-1301 USA

*/


////////////////////////////////////////////////////////////////

_jlog.prototype = new _fss('jlog','JavaScript Log Observation Glasses','1.0f','2006 Tagata Akira','http://www.tagata.org/software/');

// 1.0e 2006-12-06
// 1.0f 2007-03-07 changed visibility to display for Safari


// properties user can preset
//	_jlog.prototype._jlOffStartup
//	_jlog.prototype._jlLevel
//	_jlog.prototype._jlIsBelow
//	_jlog.prototype.lablel* (for your labels)
//	_jlog.prototype.hw* (for history window style)

//_jlog.prototype._jlOffStartup	= false;
_jlog.prototype._jlLevel	= 0;
_jlog.prototype._jlIsBelow	= false;

//_jlog.prototype._jlHideJlogButtonOnStarup = false;

// 1.0e
_jlog.prototype._jOpId = 'jl-operation';
_jlog.prototype._jlInsertBeforeReferenceId = null;

_jlog.prototype.labelInc	= '+';
_jlog.prototype.labelDec	= '-';
_jlog.prototype.labelAbove	= 'above';
_jlog.prototype.labelBelow	= 'below';
_jlog.prototype.labelMode	= 'mode';
_jlog.prototype.labelAlert	= 'alert';
_jlog.prototype.labelLog	= 'log';
_jlog.prototype.labelHide	= 'hide';
_jlog.prototype.labelDisplay	= 'display';
_jlog.prototype.labelInit	= 'init';
_jlog.prototype.labelLevel	= 'level';

// 1.0e
//_jlog.prototype.hwWidth		= '30em';
_jlog.prototype.hwWidth		= '100%';
_jlog.prototype.hwHeight	= '20em';
_jlog.prototype.hwFontSize	= 'smaller';
_jlog.prototype.hwBackgroundColor	= '#ccccff';
_jlog.prototype.hwBorder	= '1px inset #ccccff';
_jlog.prototype.hwPadding	= '0.5ex';
_jlog.prototype.hwOverflow	= 'auto';

////////////////////////////////
// constructor function
////////////////////////////////
function _jlog(ini,jlOpId) {

	this._jlIni = ini;

	// 1.0e
	if (jlOpId) {
		this._jOpId = jlOpId;
	}
	this._jlOperationElement = this.elementIdentified(this._jOpId,'div');
//	this._jlOperationElement.style.border = '1px solid #ff0000';
	if (this._jlOperationElement._fssGenerated) {
		// 1.0e
		var reference = null;
		if (this._jlInsertBeforeReferenceId) {
			reference = document.getElementById(this._jlInsertBeforeReferenceId);
		}
		if (!reference)
			reference = document.body.firstChild;
		this._jlOperationElement.style.minHeight = '0';
		document.body.insertBefore(this._jlOperationElement,reference);
//		document.body.appendChild(this._jlOperationElement);
//		this._jlOperationElement.style.position = 'absolute';
//		this._jlOperationElement.style.top =   '1em';
//		this._jlOperationElement.style.right = '1em';
	}

	this._jlAbove = this._jlIsBelow? false: true;

	// log level
	this._jlLevelElement = document.createElement('span');
	this._jlLevelUpdate(this._jlLevel);


	////////////////////////////////////////////////////////////////
	// controls
	////////////////////////////////////////////////////////////////

	// increment
	var inc = document.createElement('input');
	inc.$o = this;
	inc.type = 'button';
	inc.value = this.labelInc;
	inc.onclick = this._jlLevelInc;

	// decrement
	var dec = document.createElement('input');
	dec.$o = this;
	dec.type = 'button';
	dec.value = this.labelDec;
	dec.onclick = this._jlLevelDec;

	// range
	var optAbove = document.createElement('option');
	optAbove.value = this.labelAbove;
	optAbove.appendChild(document.createTextNode(this.labelAbove));

	var optBelow = document.createElement('option');
	optBelow.value = this.labelBelow;
	optBelow.appendChild(document.createTextNode(this.labelBelow));

	var rangeSelect = document.createElement('select');
	rangeSelect.appendChild(optAbove);
	rangeSelect.appendChild(optBelow);
	rangeSelect.selectedIndex = this._jlAbove ? 0: 1;;


	// mode select
	var modeLabel = document.createElement('span');
	modeLabel.appendChild(document.createTextNode(this.labelMode));

	var optAlert = document.createElement('option');
	optAlert.value = this.labelAlert;
	optAlert.appendChild(document.createTextNode(this.labelAlert));

	var optLog = document.createElement('option');
	optLog.value = this.labelLog;
	optLog.appendChild(document.createTextNode(this.labelLog));

	var modeSelect = document.createElement('select');
	modeSelect.appendChild(optLog);
	modeSelect.appendChild(optAlert);
	modeSelect.selectedIndex = 0;


	// log select
	var logLabel = document.createElement('span');
	logLabel.appendChild(document.createTextNode(this.labelLog));

	var optHide = document.createElement('option');
	optHide.value = this.labelHide;
	optHide.appendChild(document.createTextNode(this.labelHide));

	var optDisplay = document.createElement('option');
	optDisplay.value = this.labelDisplay;
	optDisplay.appendChild(document.createTextNode(this.labelDisplay));

	var logSelect = document.createElement('select');
	logSelect.appendChild(optHide);
	logSelect.appendChild(optDisplay);
	logSelect.selectedIndex = 0;


	// init button
	var initButton = document.createElement('input');
	initButton.type = 'button';
	initButton.value = this.labelInit;

	var myName = _jlog.prototype._fssName();
	var myVersion = _jlog.prototype._fssVer();
	var myDesc = _jlog.prototype._fssDesc();

	this._jlToggleJlog = document.createElement('input');
	this._jlToggleJlog.type = 'button';
	this._jlToggleJlog.value = myName;
	var info = 'DOUBLE CLICK to toggle '+myName;
	this._jlToggleJlog.title = info;
	var myInfo = myName+' ('+myDesc+') ';
	var ver = 'v'+myVersion;

	this._jlInfoElement = document.createElement('span');
	this._jlInfoElement.appendChild(document.createTextNode(myInfo+ver));
	this._jlInfoElement.style.backgroundColor = '#666699';
	this._jlInfoElement.style.border = '1px outset #666699';
	this._jlInfoElement.style.color = '#ffffff';
	this._jlInfoElement.style.marginRight = '0.5ex';
	this._jlInfoElement.style.padding = '0 1ex';
	this._jlInfoElement.style.visibility = 'hidden';

	var jlogTitle = document.createElement('div');
	jlogTitle.style.textAlign = 'right';
	jlogTitle.appendChild(this._jlInfoElement);
	jlogTitle.appendChild(this._jlToggleJlog);

	rangeSelect.$d = this; // for event
	modeSelect.$d = logSelect.$d = initButton.$d = this; // for event
	this._jlToggleJlog.$d = this; // for event

	////////////////////////////////////////////////////////////////
	// log history
	////////////////////////////////////////////////////////////////
	this._jlHistory = document.createElement('div');

	this._jlHistory.str = document.createElement('div');
	this._jlHistory.appendChild(this._jlHistory.str);

	this._jlHistory.str.ondblclick = this._jlClear;

	////////////////////////////////////////////////////////////////
	// operation
	////////////////////////////////////////////////////////////////
	var opCtrls = document.createElement('div');

	// 1.0e
	opCtrls.style.textAlign = 'right';
	this._jlHistory.style.textAlign = 'left';

	modeLabel.style.marginLeft = '1ex';
	logLabel.style.marginLeft = '1ex';
	initButton.style.marginLeft = '1ex';

	opCtrls.appendChild(document.createTextNode(this.labelLevel));
	opCtrls.appendChild(dec);
	opCtrls.appendChild(this._jlLevelElement);
	opCtrls.appendChild(inc);
	opCtrls.appendChild(rangeSelect);

	opCtrls.appendChild(modeLabel);
	opCtrls.appendChild(modeSelect);
	opCtrls.appendChild(logLabel);
	opCtrls.appendChild(logSelect);
	opCtrls.appendChild(initButton);
	opCtrls.appendChild(this._jlHistory);
	this._jlOpCtrls = opCtrls;

	////////////////////////////////////////////////////////////////
	// form
	////////////////////////////////////////////////////////////////
	var form = document.createElement('form');
	this._jlOperationForm = form;

	// 1.0e
	form.style.margin = '0';

	form.appendChild(jlogTitle);
	form.appendChild(opCtrls);

	this._jlHistory.style.width = this.hwWidth;
	this._jlHistory.style.height = this.hwHeight;
	this._jlHistory.style.fontSize = this.hwFontSize;
	this._jlHistory.style.backgroundColor = this.hwBackgroundColor;
	this._jlHistory.style.border = this.hwBorder;
	this._jlHistory.style.padding = this.hwPadding;
	this._jlHistory.style.overflow = this.hwOverflow;


	////////////////////////////////////////////////////////////////
	// append form
	////////////////////////////////////////////////////////////////
	this._jlOperationElement.appendChild(form);


	////////////////////////////////////////////////////////////////
	// events
	////////////////////////////////////////////////////////////////

	rangeSelect.onchange = this._jlRangeSelectChange;
	rangeSelect.onchange.call(rangeSelect); // init _jlAbove

	modeSelect.onchange = this._jlModeSelectChange;
	modeSelect.onchange.call(modeSelect); // init _jlModeValue

	logSelect.onchange = this._jlLogSelectChange;
	logSelect.onchange.call(logSelect); // init _jlLogValue

	initButton.onclick = this._jlInitButtonClick;

	this._jlToggleJlog.onmouseover = this._jlToggleJlogMouseOver;
	this._jlToggleJlog.onmouseout =  this._jlToggleJlogMouseOut;

	this._jlToggle = this._jlOffStartup? 1: 0; // init
	this._jlToggleJlog.ondblclick = this._jlToggleJlogDblclick;
	this._jlToggleJlog.ondblclick.call(this._jlToggleJlog);


	if (this._jlHideJlogButtonOnStartup && this._jlOffStartup)
		this._jlHideJlogButton();

	_jlog.prototype._fssInsertUrl();
}
/* ---------------------------------------------------------------- */

////////////////////////////////////////////////////////////////
// event methods
////////////////////////////////////////////////////////////////
// log level
_jlog.prototype._jlLevelUpdate = function (lvl) {
	while(this._jlLevelElement.firstChild) {
		this._jlLevelElement.removeChild(this._jlLevelElement.firstChild);
	}
	this._jlLevelElement.appendChild(document.createTextNode(lvl));
};
// inc
_jlog.prototype._jlLevelInc = function () {
	this.$o._jlLevelUpdate(++this.$o._jlLevel);
};
// dec
_jlog.prototype._jlLevelDec = function () {
	this.$o._jlLevelUpdate(--this.$o._jlLevel);
};
// range select
_jlog.prototype._jlRangeSelectChange = function () {
	this.$d._jlAbove = (this.value == this.$d.labelAbove)? true: false;
};
// mode select
_jlog.prototype._jlModeSelectChange = function () {
	this.$d._jlModeValue = this.value;
};
// log select
_jlog.prototype._jlLogSelectChange =  function () {
	this.$d._jlLogValue = this.value;
	if (this.$d._jlLogValue == this.$d.labelHide) {
		this.$d._jlHistory.style.display = 'none';
	}
	else {
		this.$d._jlHistory.style.display = 'block';
	}
};
// init
_jlog.prototype._jlInitButtonClick = function () {
	this.$d._jlIni && this.$d._jlIni();
};
// toggle jlog mouseover
_jlog.prototype._jlToggleJlogMouseOver = function () {
	if (!this.$d._jlToggle)
		this.$d._jlInfoElement.style.visibility = 'visible';
};
// toggle jlog mouseout
_jlog.prototype._jlToggleJlogMouseOut = function () {
	if (!this.$d._jlToggle)
		this.$d._jlInfoElement.style.visibility = 'hidden';
};
// toggle jlog dblclick
_jlog.prototype._jlToggleJlogDblclick = function () {
	var display, visibility;
	if (this.$d._jlToggle ^= 1) {
		display = 'block';
		visibility = 'visible';
	}
	else {
		display = 'none';
		visibility = 'hidden';
	}
	this.$d._jlOpCtrls.style.display = display;
	this.$d._jlInfoElement.style.visibility = visibility;
};


// hide jlog button
_jlog.prototype._jlHideJlogButton = function () {
// 1.0f 2007-03-06 changed visibility to display for Safari
//	this._jlToggleJlog.style.visibility = 'hidden';
	this._jlToggleJlog.style.display = 'none';
	document.$_jlo = this;
	document.onkeypress = function (e) {
		var code;
		if (!e) var e = window.event;
		if (e.keyCode) code = e.keyCode;
		else if (e.which) code = e.which;
//		var character = String.fromCharCode(code);
		if (code == 27 && e.shiftKey)
//			this.$_jlo._jlToggleJlog.style.visibility = 'visible';
			this.$_jlo._jlToggleJlog.style.display = 'inline';
	};
}

////////////////////////////////////////////////////////////////
// jlog log method
////////////////////////////////////////////////////////////////
_jlog.prototype._jlHistoryPuts = function (s) {
	var y = document.createElement('div');
	y.appendChild(document.createTextNode(s));
	this._jlHistory.str.appendChild(y);
};
_jlog.prototype._jlClear = function () {
	while(this.firstChild) {
		this.removeChild(this.firstChild);
	}
};
_jlog.prototype._jlPuts = function (s,level) {
	level = level || 0;
	if (this._jlToggle &&
		(this._jlAbove?
			(this._jlLevel <= level):
			(this._jlLevel >= level))) {
		var logstring = '['+level+'] '+s;
		if (this._jlModeValue == this.labelAlert) {
			alert(logstring);
		}
		else if (this._jlModeValue == this.labelLog) {
			this._jlHistoryPuts(logstring);
		}
		else {
		}
	}
};

