/**
 *  xdbgui.js
 *
 * +================================================================================================+
 * | Javascript utilities for use with the xmldbgui.php
 * |
 * +------------------------------------------------------------------------------------------------+
 * | Copyright:
 * |
 * | xdbgui.js: Utilities for use with the guis built from the xdbgui template
 * |
 * | Copyright (C) 2002-2003 Nigel Swinson, nigelswinson@users.sourceforge.net
 * |
 * | 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 * +================================================================================================+
 *
 * @author  Nigel Swinson
 * @link    http://sourceforge.net/projects/phpxmldb/
 * @version 1.1.2 beta
 * @CVS $Id:  Exp $
 */

// In order to avoid polluting the global namespace, we hide the default helpers in a CXDbGui object.

////////////////////////////////////////////////////////////////////////////////////////////////////
// Page object

// Constructor
window.CPage=function(Page) {
	if (arguments.length <= 0) return;
	this.Init(Page);
}

// Initialiser
CPage.prototype.Init = function(Page) {
	// The url to this page
	this.Page = Page;	
	// Panels that show and hide as a result of top level actions
	this.ActionPanelNames = new Array('AddPanel', 'HelpPanel');
	// Where images come from
	this.ImagesPath = '';
}

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

// Constructor
window.CField = function(Name, Value) {
	if (arguments.length <= 0) return;
	this.Init(Name, Value);
}

// Initialiser
CField.prototype.Init = function(Name, Value) {
	this.Name = Name;
	this.Value = Value;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Encoding helpers

// Convert <>"'& to the corresponding entities
htmlspecialchars = function (Source) {
	Target = new String(Source)
	Target = Target.replace(/&/g, '&amp;');
	Target = Target.replace(/</g, '&lt;');
	Target = Target.replace(/>/g, '&gt;');
	Target = Target.replace(/\"/g, '&quot;');
	Target = Target.replace(/\'/g, '&#039;');
	return Target;
}

// Markup flat strings as html by inserting <p> tags at double line breaks and
// <br> tags at single line breaks.
function MarkupParagraphs(PlainTextString) {
	// Quick way out.
	if (!PlainTextString) return "";

	// Replace all \n\n combinations with </p><p>
	var MarkedUpString = PlainTextString.replace(/\n\n/g, "</p><p>");
	if (MarkedUpString != PlainTextString) {
		// If we have a string, then prefix it with <p> and postfix it with </p>
		MarkedUpString = "<p>" + MarkedUpString + "</p>";
	}

	// Replace all \n occurences with <br>
	MarkedUpString = MarkedUpString.replace(/\n/g,"<br>\n");

	// ###  It might be a good idea ot preserve as much preformatted text as possible,
	// you can do this by catching all lines that start with a space, and treat them
	// as prefromatted text.
	// Also any lines containing only whitespace should be modified to contain nothing
	// And then three blank lines in a row is a <br> between paragraphs.

	// All done :o)
	return MarkedUpString;
}

/**
*
*  UTF-8 data encode / decode
*  http://www.webtoolkit.info/
*
**/
var Utf8 = {

    // public method for url encoding
    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;
    },

    // public method for url decoding
    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;
    }
}

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

// Turns a label and value into a string of html
CField.prototype.ToHtml = function() {
	Result = '<span class="inputgroup">'
			+'<span class="inputlabel">'
			+ htmlspecialchars(this.Name)
			+ ':</span>'
			+'<span class="inputcontrol">'
			+ htmlspecialchars(this.Value)
			+'</span>'
			+'</span>';
	return Result;
}

// Turns a label and value into a <input> with the specified attributes
CField.prototype.ToInputControl = function(Attributes) {
	Result = '<input name="' + this.Name + '" ' + Attributes + ' value="'
			+ htmlspecialchars(this.Value)
			+'">';
	return Result;
}

// Turns a label and value into a textarea with the specified attributes
CField.prototype.ToTextArea = function(Attributes) {
	Result = '<textarea name="' + this.Name + '" ' + Attributes + '>'
			+ htmlspecialchars(this.Value)
			+'</textarea>';
	return Result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Form helpers

CPage.prototype.ClearForm = function(InputElement) {
	if (!InputElement) return;
	var oForm = InputElement.form;
	if (!oForm) return;
	for (i = 0; i < oForm.length; i++) {
		var oInputControl = oForm.elements[i];
		if (!oInputControl) continue;
		if (oInputControl.type == 'text') oInputControl.value = '';		
		if (oInputControl.type == 'textarea') oInputControl.value = '';		
	}	
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Panel helpers

// Called to show a panel
CPage.prototype.ShowPanel = function(PanelName) {
	// Find the panel using DOM Html
	var oPanel = document.getElementById(PanelName);
	if (!oPanel) return;

	oPanel.style.display = 'display';
}

// Called to hide a panel
CPage.prototype.HidePanel = function(PanelName) {
	// Find the panel using DOM Html
	var oPanel = document.getElementById(PanelName);
	if (!oPanel) return;

	oPanel.style.display = 'none';
}

// Called to hide/show a panel
CPage.prototype.TogglePanel = function(PanelName) {
	// Find the panel using DOM Html
	var oPanel = document.getElementById(PanelName);
	if (!oPanel) return;

	if (oPanel.style.display == 'none') {
		oPanel.style.display = 'block';
	} else {
		oPanel.style.display = 'none';
	}
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// AJAX object

// Builds a callback control
window.AjaxCallback = function(
				// The object on which to call the callback
				oParent, 
				// The callback function
				Callback) {
	// Store callback parameters
	this.oParent = oParent;
	this.Callback = Callback;
	/*@cc_on
	@if (@_jscript_version >= 5)
		// First off look for the COM object 
		try {
			this.xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e1) {
			try {
				this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (e2) {
				this.xmlhttp = false;
			}
		}
	@else
		this.xmlhttp = false;
	@end @*/
	
	// If we don't yet have xmlhttp defined, then it might be a native type
	if (!this.xmlhttp && typeof XMLHttpRequest != 'undefined') {
		try {
			this.xmlhttp = new XMLHttpRequest();
		} catch (e) {
			this.xmlhttp = false;
		}
	}
}

// Send the PostData to the Page specified
AjaxCallback.prototype.Send = function(Page, Data) {
	var oCallback = this;
	this.xmlhttp.onreadystatechange = function() {
		if (oCallback.xmlhttp.readyState == 4) {
			if (oCallback.xmlhttp.status == 200) {
				oCallback.Complete();
			} else {
				oCallback.Error();
			}
		}
	}
	this.xmlhttp.open("POST", Page);
	this.xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');	
	this.xmlhttp.send(Data);
}

// Called on error.  By default alert()s the user of the error
AjaxCallback.prototype.Error = function() {
	alert("Error while processing callback");
}

// Called when the request is complete.  By default executes oParent.Callback(xmlhttp)
AjaxCallback.prototype.Complete = function() {
	eval('this.oParent.' + this.Callback + '(this.xmlhttp);');
}
