var xmlHttp

/*function getForm(str)
{ 
xmlHttp=GetXmlHttpObject()
if (xmlHttp==null)
 {
 alert ("Browser does not support HTTP Request")
 return
 }
var url="/index.php?task=ajax"
url=url+"&type="+str
if(getForm.arguments[1]!=null)
{
url=url+"&id="+getForm.arguments[1]
}
xmlHttp.open("GET",url,true)
xmlHttp.onreadystatechange=stateChanged 
xmlHttp.send(null);
}

function stateChanged() 
{ 
if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete")
 { 
 response = xmlHttp.responseText;
 } 
}
*/
function GetXmlHttpObject()
{
var xmlHttp=null;
try
 {
 // Firefox, Opera 8.0+, Safari
 xmlHttp=new XMLHttpRequest();
 }
catch (e)
 {
 //Internet Explorer
 try
  {
  xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
  }
 catch (e)
  {
  xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
 }
return xmlHttp;
}
/**
 * Class: InlineEditor
 *
 * Version 0.1 (pending)
 *
 * License: Public Domain
 *
 *
 * User-overridable functions:
 * More documentation further down in code.
 *
 *    InlineEditor.customEditor      = function( theElement ) { ...
 *    InlineEditor.editorValue    = fuction( theEditor ) { ...
 *    InlineEditor.elementValue   = function( theElement ) { ...
 *    InlineEditor.elementChanged = function( theElement, oldVal, newVal ) { ...
 *
 *
 * Key CSS class names:
 *    editable:   Tables with this class will have their 'td' cells made editable.
 *    uneditable: At event time, cells with this class will NOT be editable.
 *    editing:    When editing, the 'td' element will have this class.
 *
 *
 * Useful utility functions:
 *
 *    InlineEditor.addClass( element, classname )
 *        Adds classname to the 'class' attribute of the element.
 *
 *    InlineEditor.removeClass( element, classname )
 *        Removes classname from the 'class' attribute of the element.
 *
 *    InlineEditor.checkClass( element, classname )
 *        True if class attribute of the element contains classname, false otherwise.
 *
 *    InlineEditor.swapClass( element, classname1, classname2 )
 *        Replaces classname1 with classname2 in class attribute of the element.
 *
 *     InlineEditor.columnNumer( cell )
 *        Returns column number of cell (zero index) or -1 if there are problems.
 *
 *     InlineEditor.rowNumer( cell )
 *        Returns row number of cell (zero index) or -1 if there are problems.
 *
 *     InlineEditor.rowID( cell )
 *        Returns row ID, useful if you use that to tie to a database primary key.
 *
 *
 * Change Log:
 *
 *    v0.1.1 - More reliable window.onload event adding. Added customEditor
 *             extensible function.
 *    v0.1 - Initial release.
 *
 *
 * Author:
 *
 *    Robert Harder
 *    rharder # users,sf,net
 */

/** Global var to test for IE */
var inlineeditor_isIE = ( navigator.userAgent.toLowerCase().search( 'msie' ) != -1 && navigator.userAgent.toLowerCase().search( 'opera' ) == -1 ) ? true : false;

var InlineEditor = {

/* ********  F U N C T I O N S   Y O U   M I G H T   C A L L  ******** */


    alreadyInited : false,  // In case we get called twice.



    /**
     * This should be called automatically when the page loads,
     * but if you also are setting up a function to run on
     * window.onload then this might get bumped out of position.
     * If that's the case, then make sure you call InlineEditor.init()
     * yourself.
     *
     * If you create some nodes programmatically, you can also rerun
     * this code to scan for "editable" classes. Like this:
     *
     * var foo document.createElement('div');
     * foo.className = 'editable';
     * ...
     * InlineEditor.init( foo );
     */
    init: function( arg )
    {
        // What is the arg?
        var isNode  = false;
        var isEvent = false;
        if( arg.nodeType )
            isNode = true;

        // If we're already inited and we're not being asked to
        // init a new a node, bail out.
        if( !isNode && InlineEditor.alreadyInited )
            return;

        // Find all elements with class 'editable' and make them editable
        var rootEl = isNode ? arg : document;
        var allEl = rootEl.getElementsByTagName('*');
        for (var i= 0; i < allEl.length; i++ ){
            if( InlineEditor.checkClass( allEl[i], 'editable' ) ){

                switch( allEl[i].tagName ){

                    // For tables, set up individual cells.
                    case 'TABLE':
                        var tds = allEl[i].getElementsByTagName( 'td' );
                        for( var j = 0; j < tds.length; j++ )
                            InlineEditor.recursiveAddOnClickHandler( tds[j] );
                        break;

                    // Default behavior is to set up all editable elements
                    // which requires setting up all its children elements.
                    // This shouldn't be necessary, but these 'dblclick' events
                    // don't seem to propagate through the elements  to parents.
                    default:
                        InlineEditor.recursiveAddOnClickHandler( allEl[i] );
                }   // end switch: tagname


            }   // end if: editable
        }   // end for: each element

        if( !isNode )
            InlineEditor.alreadyInited = true;
    },  // end init



    addClass:    function(o,c)     { return InlineEditor.jscss('add',o,c); },
    removeClass: function(o,c)     { return InlineEditor.jscss('remove',o,c); },
    checkClass:  function(o,c)     { return InlineEditor.jscss('check',o,c); },
    swapClass:   function(o,c1,c2) { return InlineEditor.jscss('swap',o,c1,c2); },


    /**
     * Return the column number, if a table cell.
     */
    columnNumber: function( cell )
    {
        // Ensure we have a 'td' cell
        if( cell.nodeType != 1    ) return -1;
        if( cell.tagName  != 'TD' ) return -1;

        // Find cell and return column number
        if( !cell.parentNode || cell.parentNode.tagName != 'TR' ) return -1;
        var tr  = cell.parentNode;
        var tds = tr.getElementsByTagName('TD');
        for( var i = 0; i < tds.length; i++ )
            if( tds[i] == cell )
                return i;

        return -1;
    },  // end columnNumber


    /**
     * Return the row number, based on the row's immediate
     * parent, which may be a 'tbody' or the actual 'table'.
     */
    rowNumber: function( cell )
    {
        // Ensure we have a 'td' cell
        if( cell.nodeType != 1    ) return -1;
        if( cell.tagName  != 'TD' ) return -1;

        // Find cell's parent row and return row number
        if( !cell.parentNode || cell.parentNode.tagName != 'TR' ) return -1;
        var tr  = cell.parentNode;
        var trs = tr.parentNode.childNodes;
        for( var i = 0; i < trs.length; i++ )
            if( trs[i] == tr )
                return i;

        return -1;
    },  // end rowNumber



    /**
     * Returns the ID of the parent row. Useful if you use
     * that to track the row to some sort of database primary key.
     */
    rowID: function( cell )
    {
        // Ensure we have a 'td' cell
        if( cell.nodeType != 1    ) return -1;
        if( cell.tagName  != 'TD' ) return -1;

        if( !cell.parentNode || cell.parentNode.tagName != 'TR' ) return -1;
        var tr = cell.parentNode;
        return tr.id;
    },  // end rowID


    sizeTo: function( changeMe, model )
    {
        changeMe.style.position = 'absolute';
        changeMe.style.zindex = 99;
        changeMe.style.left   = model .offsetLeft + 'px';
        changeMe.style.top    = model .offsetTop + 'px';
        changeMe.style.width  = model .offsetWidth + 'px';
        changeMe.style.height = model .offsetHeight + 'px';

        return changeMe;
    },  // end sizeTo


	getID: function( id )
	{

        var request = GetXmlHttpObject(); // I was using Google's tools
        var url = "/index.php?task=ajax&call=edit&id=" + id;

        request.open("GET", url, true);
        request.onreadystatechange = function() {
            if (request.readyState == 4) {
		if( navigator.appName == "Opera" )
		{
			document.getElementById("ebox").value = request.responseText;
		}
		else
		{
          		document.getElementById("ebox").innerHTML = request.responseText;
		}

            }   // end if: readystate 4
        }; // end onreadystatechange

        request.send(null);
	},

	getHTML: function( id )
	{

        var request = GetXmlHttpObject(); // I was using Google's tools
        var url = "/index.php?task=ajax&call=editHTML&id=" + id;

        request.open("GET", url, true);
        request.onreadystatechange = function() {
            if (request.readyState == 4) {
               document.getElementById(id).innerHTML = request.responseText;

            }   // end if: readystate 4
        }; // end onreadystatechange

        request.send(null);
	},

/* ********  F U N C T I O N S   Y O U   M I G H T   O V E R R I D E  ******** */


    // These are examples of how you might override certain functions
    // if you want to add more complex behaviors.


    // The default editor is a one-line 'input' element.
    // If you need anything more complex like a textarea
    // or a select box or something, return it here.
    //
    // Remember to code the following:
    //
    //    - Set the editor's starting value
    //    - Set the editor's size
  
/*  //
   InlineEditor.customEditor: = function( theElement )
    {
        // Only interested in setting up something custom
        // for paragraph tags.
        if( theElement.tagName != 'span' )
            return;

        var editor = document.createElement( 'textarea' );
        editor.innerHTML    = theElement.innerHTML;
        editor.style.width  = "100%";
        editor.style.height = theElement.offsetHeight + "px";

        return editor;
    }   // end customEditor



    // If you use a custom editor, you may need to provide a
    // way to determine what the value is. The default behavior,
    // which will still take over if you return nothing, is
    // to check for the presence of the 'value' property.
    // If your editor has no 'value' property then the 'innerHTML'
    // property is used. If this suits your needs
    // even with your custom editor, then there's no need to
    // use this function.
    //

    InlineEditor.editorValue = function( editor )
    {
        // Hypothetical editor with some obscure way
        // of determing what the user selection is.
            return editor.value;

    }   // end editorValue


    // If you have anything "funny" going on you're welcome
    // to define/override this function to determine just what
    // the starting value is. The default behavior, which will
    // be employed if you return nothing, is to use 'innerHTML'.
   InlineEditor.elementValue: = function( theElement )
    {
	alert(theElement);
        // Ignore the extra 'span' I threw in there. Just give me text.
        return theElement.innerText;

    }   // end elementValue



    // Unless you just want people to dink around with the
    // transient-by-nature current page, you'll probably want
    // to define/override this function and do something that
    // saves the user's changes. Here is an example using
    // "ajax" to immediately post a change. In this case,
    // I was using Google's Map APIs, so that's how I create
    // the HttpRequest.
    //
*/
    elementChanged: function( id, newVal,theElement )
    {
        InlineEditor.addClass( theElement, 'uneditable' ); // Special InlineEditor class


        var request = GetXmlHttpObject(); // I was using Google's tools
	var newvale = newVal.replace(/\n/g, '.||.');
	var url = "/index.php?task=ajax&call=upedit&id=" + id +"&text=" + newvale;

        request.open("GET", url, true);
        request.onreadystatechange = function() {
            if (request.readyState == 4) {

                InlineEditor.removeClass( theElement, 'uneditable' );
		 document.getElementById(id).innerHTML = request.responseText;
            }   // end if: readystate 4
        };  // end onreadystatechange
        request.send(null);

    },  // end elementChanged




   

 // end elementChanged

/* ********  F U N C T I O N S   Y O U   S H O U L D   N O T   C A L L  ******** */


    recursiveAddOnClickHandler: function( element )
    {
        element.onclick = InlineEditor.handleOnClick;

        if( element.childNodes ){
            children = element.childNodes;
            for( i = 0; i < children.length; i++ ){
                if( children[i].onclick ){

                    InlineEditor.recursiveAddOnClickHandler( children[i] );

                }   // end if: child also needs handler
            }   // end for: each child
        }   // end if: children
    },   // end recursiveAddOnClickHandler



    /**
     * Called when element is double-clicked.
     * At the time of this event, the class is checked to see
     * if the cell is marked 'uneditable'.
     */
    handleOnClick: function( evt )
    {
        var evt = InlineEditor.fixEvent( evt );
        //var target = evt.target;
        var target = InlineEditor.findEditableTarget( evt.target );
        // If element is "uneditable" or "editing" don't edit.
        if( InlineEditor.checkClass( target, 'uneditable' ) || InlineEditor.checkClass( target, 'editing' ) )
            return;

        // Save original value.
        var oldHTML = target.innerHTML;
        var oldVal  = null;
        if( InlineEditor.elementValue )      // USER CAN PROVIDE OVERRIDE FUNCTION
            oldVal = InlineEditor.elementValue( target );
        if( !oldVal )
            oldVal = target.innerHTML;

        // Set up editor element
        // User overridable function
        var editor = null;
        if( InlineEditor.customEditor ){     // USER CAN PROVIDE OVERRIDE FUNCTION

            editor = InlineEditor.customEditor( target );

        }   // end if: customEditor

        if( !editor ) { // If user didn't provide custom editor

            
        editor = document.createElement('textarea')
                //editor.innerHTML = oldVal;
		editor.setAttribute('id','ebox')
		editor.setAttribute('name','ebox')
		
//                editor.style.position = 'absolute';
//                editor.style.zindex = 99;
//                editor.style.left   = target.offsetLeft + 'px';
//                editor.style.top    = target.offsetTop + 'px';
                editor.style.width  = '500px';
                editor.style.height = '70px';
       
        }   // end else: default

        // Listen for when focus is lost.
        editor.onblur = function(){ InlineEditor.handleInputBlur( editor, target.id, oldVal, oldHTML ); }

        // Prep target
        InlineEditor.addClass( target, 'editing' );

        // Add editor
	InlineEditor.getID(target.id);
        target.innerHTML = "";
        target.appendChild( editor );
        editor.focus();
		
        return false; // Don't propagate up. No need. Right?
    },   // end handleDoubleClick


    /**
     * Called when user is done editing the cell.
     */
    handleInputBlur: function( editor, id, oldVal, oldHTML )
    {
        // Gather values
        var parent = editor.parentNode;
        var newVal = null;
        if( InlineEditor.editorValue )
            newVal = InlineEditor.editorValue( editor );
        if( !newVal )
            newVal = editor.value ? editor.value : editor.innerHTML; // Fallback

        // Save value in the element
        
        // If user wants to know of the change, pass it on.
        if( InlineEditor.elementChanged )
            InlineEditor.elementChanged( id, newVal, parent );

	//InlineEditor.getHTML(id);
        InlineEditor.removeClass( parent, 'editing' );


    },   // end handleInputBlur


    /**
     * Thanks to http://www.onlinetools.org/articles/unobtrusivejavascript/cssjsseparation.html
     * for this bit of code.
     */
    jscss: function(a,o,c1,c2)
    {
        switch (a){
            case 'swap':
                o.className=!InlineEditor.jscss('check',o,c1) ?
                    o.className.replace(c2,c1) :
                    o.className.replace(c1,c2);
                break;
            case 'add':
                if(!InlineEditor.jscss('check',o,c1)){o.className+=o.className?' '+c1:c1;}
                break;
            case 'remove':
                var rep=o.className.match(' '+c1)?' '+c1:c1;
                o.className=o.className.replace(rep,'');
                break;
            case 'check':
                return new RegExp('\\b'+c1+'\\b').test(o.className)
                break;
        }   // end switch: action
    },  // end jscss


    fixEvent: function( evt )
    {
        var E = evt ? evt : window.event; // 'event' seems to be a special word in IE, so I'm using 'E' instead.
        if( E.target )
            if( E.target.nodeType == 3 )
                E.target = E.target.parentNode;

        //make sure Opera doesn't set this object
        if( inlineeditor_isIE )
            if( E.srcElement )
                E.target = E.srcElement;

        return E;
    },   // end fixEvent


    findEditableTarget: function( target )
    {
        // If a table cell, we assume that's editable
        if( target.nodeType == 1 && target.tagName == 'TD' )
            return target;

        if( InlineEditor.checkClass( target, 'editable' ) )
            return target;

        if( target.parentNode )
            return InlineEditor.findEditableTarget( target.parentNode );

        return null;
    },  // end findEditableTarget


    addEvent: function( target, eventName, func, capture )
    {
        if( target.addEventListener ){
            target.addEventListener( eventName, func, capture );
            return true;
        }   // end if: addEventListener
        else if( target.attachEvent )
            return target.attachEvent( 'on'+eventName, func );
    },  // end addEvent


    removeEvent: function( target, eventName, func, capture )
    {
        if( target.removeEventListener ){
            target.removeEventListener( eventName, func, capture );
            return true;
        }   // end if: removeEventListener
        else if( target.detachEvent )
            return target.detachEvent( 'on'+eventName, func );
    }   // end removeEvent

}   // end class InlineEditor

/**
 * Add InlineEditor.init() to window.onload.
 */
InlineEditor.addEvent(window,'load',InlineEditor.init,false);
