

/*================================================================================
    ajaxControllers.js

    author:     mbae@bcwin.ch, Marc Bächinger
    created:    2005/11/03

    depends on:
    (*)  myrico.js (my modified version of Rico 1.1-beta2) 
         (http://www.openrico.org)  
    (**) prototype 1.3.1   
         (http://prototype.conio.net/)

    Contains:
    ---------
    (a) SingleTargetController
    (b) more to come...

===================================================================================*/

    /**
     * class SingleTargetController
     * 
     * should be a generic approach to connect a form to a rico.js/prototype.js in a rather generic
     * way. The aim is to map a form (or link?) to a request
     *
     *
     * 1. Create a xhtml page which contains
     *   
     *    1.1. Elements on xhtml page
     *
     *      (1) a 'div' element (target element) with an given id in which the result of an 
     *              ajax request should be inserted (former content of that element will be lost on refresh)
     *      (2) An optional form with input fields. The names and values of the inputs are appended to the
     *              ajax request as GET or POST parameters
     *      (3) An optional intermediary element which is inserted into the target element while the action
     *              is going on. If the response is ready the element will be removed, but kept for reuse.
     *      
     *    1.2.  Naming convention 
     *      
     *      Names and ids of involved xhtml elements must follow a naming convention for intended results:
     *
     *      (1) target element id         ->  <controllerName>
     *      (2) form with user input      ->  <controllerName>
     *      (3) intermediaty element id   ->  <controllerName>
     *
     *
     * 2. Create a SingleTargetController instance:
     *
     *      var myController = new SingleTargetController();
     *
     * 3. Configure it 
     *      
     *      myController.ajaxSetup(name);
     *
     *          @param name                     The name of the controller from which the names and ids 
     *                                              of the form, the target element and the intermediate
     *                                              element is derived 
     *
     *  4. Fire it
     *  
     *        myController.ajaxInitiate(requestName);
     *
     *          @param requestName              The name of a registered request to trigger
     */
    var SingleTargetController = Class.create();


    SingleTargetController.prototype = {

        initialize: function() {
        },


       /**
        * setup for the ajax request. 
        *
        * The name determines the names and ids of the involved xhtml elements. By default 
        * the following naming convention is applied. However you can explicitly set the name 
        * of the input form and the ids of the target and intermediate elements by using the 
        * setTargetElementId( id ), setIntermediateElementId( id ) and setFormName(name) 
        * functions of the SingleTargetController.
        */
       ajaxSetup: function( name ) {
            this.name = name;
            this.setFormName( name );
            this.setTargetElementId( name );
            this.setIntermediateElementId( name + "InterElement" );
            ajaxEngine.registerAjaxObject( name , this );
       },
       
       
       
       /**
        * initiates the ajax response. As this controller has been registered
        * as eventHandler for the notification of the completed response its 
        * 'ajaxUpdate' method is used to dispatch that event.
        *
        */
       ajaxInitiate: function(requestName) {
       
            // send search query
            // this is only possible with the hacked myrico.js
            // I added subtle changes to that code (_cretae. It' likely that these
            // changes are only needed to workoarunf my lack of knowledge 
            // about javascript or rico. It works anyway.
            ajaxEngine.sendRequest( requestName , this._getFormParams());
            
            if ( this.targetElement ) {
                if ( this.intermediateElement ) {
                    this.targetElement.innerHTML = RicoUtil.getContentAsString( this.intermediateElement );
                } else {
                    this.targetElement.innerHTML = "<div class=\"stand-by\">Aktion gestartet. Bitte warten...</div>";
                }
            }
       },
       
       /**
        * method called by the ajaxEngine after response
        * is returned from server. All elements contained in the 
        * 'reponse' element are put into a 'div' element with the class
        * attribute 'ajax-response-container'. At the end the container 
        * element is inserted into the <code>targetElement</code>
        *
        * @param ajaxResponse the response as a DOM element with name 'response'
        */
       ajaxUpdate: function(ajaxResponse) {
         this.targetElement.innerHTML = RicoUtil.getContentAsString(ajaxResponse);
       },
       

/* -------------- setters to set elements and the form holding parameter input -- */
       
       /**
        * Sets the target element of the controller. This is the element
        * in which the response of the ajax request will be inserted
        * 
        */
       setTargetElementId: function(targetId) {
            this.targetElement = $(targetId + "Target");
            if ( !this.targetElement ) {
                this.targetElement = $(targetId);
            }
       },
       
       /**
        * Sets the name of the form which contains input fields which 
        * should be appended to the request as parameters.
        * 
        * @param the id of the target element to push content into
        */
       setFormName: function(name) {
            this.formName = name;
            this.form = document.forms[name];
       },
       
       /**
        * Sets the intermediate element of the controller. This element
        * is inserted into the target element after sending the reqest until
        * the response is retrieved
        * 
        * @param intermedId the id of the intermediate content element
        */
       setIntermediateElementId: function(intermedId) {
            this.intermediateElement = $(intermedId);
       },

/* ------private functions -- */
       
       _clearTargetElement: function() {
         if ( this.targetElement && this.targetElement.childNodes.length > 0) {
            var children = this.targetElement.childNodes;
            for ( var i = 0; i < children.length; i++ ) {
                this.targetElement.removeChild( children[i] );
            }
         }
       },
       /**
        * gets all input parameters (formfields) of the form if any and
        * concatenates it to a query string ('name=value&name2=value2')
        * 
        * as first param '_controllerName' is appended to 
        * tell let the server know which controller calls.
        */
       _getFormParams: function() {
            var params = "_controllerName=" + this.name;
            if ( this.form ) {
                for ( var i = 0; i < this.form.elements.length; i++ ) {
                    params += "&" + this.form.elements[i].name + "=" + this.form.elements[i].value;
                    
                }
            }
            return params;
       }
    };   

/*
method which results after my changes on rico.js 1.1beta2 has ben applied.
Replace that code in rico.js to  make SingleTargetController work correctly


   _createQueryString: function( theArgs, offset ) {
      var queryString = ""
      for ( var i = offset ; i < theArgs.length ; i++ ) {

          if ( i != offset )
            queryString += "&";

          var anArg = theArgs[i];

          if ( anArg.name != undefined && anArg.value != undefined ) {
            queryString += anArg.name +  "=" + escape(anArg.value);
          } else {
            if ( anArg.indexOf( '&' ) < 0 ) {
                 var ePos  = anArg.indexOf('=');
                 var argName  = anArg.substring( 0, ePos );
                 var argValue = anArg.substring( ePos + 1 );
                 queryString += argName + "=" + escape(argValue);
            } else {
                 var params = anArg.split( '&' );
                 for ( var j = 0; j < params.length;j++ ) {
                     var ePos  = params[j].indexOf('=');
                     var argName  = params[j].substring( 0, ePos );
                     var argValue = params[j].substring( ePos + 1 );
                     if ( j > 0 ) {
                        queryString += "&";
                     }
                     queryString += argName + "=" + escape(argValue);
                 }
            }
          }
      }

      return queryString;
   },*/
   
   
function handleRelationToggle( ajaxRequest, ajaxResponse) {

    if ( ajaxResponse.isError() == true ) {
        alert ( 'gescheitert' );
        return;
    } 
    
    var key = ajaxResponse.getParameter( "entityName" ) + ajaxResponse.getParameter( "entityId" ) ;
    var checkBox = document.forms[ 'content.toggle.relation' ].elements[ key ];
    var task = ajaxResponse.getParameter( "task" );
    if ( task == 'add' ) {
        checkBox.checked = true;
    } else if ( task == 'remove' ) {
        checkBox.checked = false;   
    }
    
    $("feedback").innerHTML = ajaxResponse.getContentAsString();
}

var ajaxController = new AjaxController();
ajaxController.bindActionToUrl( "relation.toggle" , "/app/default/faceless/fw.action/relation.toggle" );

function toggleEntityToRelationGroup( entityName, entityId, relationGroupId, parentName, parentId , fromRow) {
    
    var action = new AjaxAction();
    action.setName( "relation.toggle" );
    action.addParam( "entityName" , entityName );
    action.addParam( "entityId" , entityId );
    action.addParam( "relationGroup" , relationGroupId );
    action.addParam( "parentName" , parentName );
    action.addParam( "parentId" , parentId );
    var checkBox = document.forms[ 'content.toggle.relation' ].elements[ entityName + entityId ];   
    var msg = "";
    if ( fromRow ) {
        if ( checkBox.checked == false) {
            action.addParam( "task" , "add" );
            msg = "Objekt wird hinzugefügt.";
        } else {
            action.addParam( "task" , "remove" );
            msg = "Objekt wird entfernt.";
        }
    } else {
        if ( checkBox.checked == true) {
            action.addParam( "task" , "add" );
            msg = "Objekt wird hinzugefügt.";
        } else {
            action.addParam( "task" , "remove" );
            msg = "Objekt wird entfernt.";
        }
    }
    var now = new Date();
    var dstring = now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds();
    $("feedback").innerHTML = "<div class=\"stand-by\">" + msg + " (" + dstring + ")</div>";
    ajaxController.fireActionToTargetFunction( action , handleRelationToggle);
}



function light( row , color) {
    var cells = row.getElementsByTagName( 'td' );
    for ( var i = 0;i<cells.length;i++ ) {
        if ( color ) {
            cells[i].style.backgroundColor = color;
        } else {
            cells[i].style.backgroundColor = "#dedede";
        }
    }
}
function unlight( row , color) {
    var cells = row.getElementsByTagName( 'td' );
    for ( var i = 0;i<cells.length;i++ ) {
        if ( color ) {
            cells[i].style.backgroundColor = color;
        } else {
            cells[i].style.backgroundColor = "#ffffff";
        }
    }
}

