/*
AJPHPList - World's Easiest JavaScript AJAX ToolKit 
ajphplist.js
Jochen Taeubrich <jotazzu@gmx.net>

## v1.0  2006-02-06 INITIAL VERSION
## v1.1r 2006-02-07 SPECIAL VERSION without relaying over rmtsubscribe.php

	** BSD LICENSE *********************************************************
	
	Copyright (c) 2006 Jochen Taeubrich
	All rights reserved.
	
	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions
	are met:
	1. Redistributions of source code must retain the above copyright
	   notice, this list of conditions and the following disclaimer.
	2. Redistributions in binary form must reproduce the above copyright
	   notice, this list of conditions and the following disclaimer in the
	   documentation and/or other materials provided with the distribution.
	3. The name of the author may not be used to endorse or promote products
	   derived from this software without specific prior written permission.
	
	THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
	IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
	OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
	DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
	THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
	THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

	************************************************************************

*/

    AJPHPlist = new Object;

    AJPHPlist.CONFIG = 
    { // these are default values and may be overwritten
      defaultSubmit    : "subscribe",  // name of the submit button which should be send as default
      defaultSubmitVal : "1"           // the correspondending value
    }

    AJPHPlist.SAVED = 
    { formcnt      : "",
      submitcmd    : "",
      submitcmdval : ""
    }

    /* --------------------------------------------- */
    AJPHPlist.checkEmail = function( email) 
    { var mailadr = email;
      var mailrgx = /^([\w-+]+[\.~'&=]?)*[\w-+]+@([^\W]+(\.|-)?)*[^\W]+\.[a-z]{2,6}$/i;

      if (mailadr.search( mailrgx) == -1)
      { alert( "Sorry, the e-mail address you entered is invalid: \n"+email);
        return false;
      }
      return true;
    }

    /* --------------------------------------------- */
    AJPHPlist.setDisplay = function( docObj, mode)
    { if (docObj!=undefined && docObj!=null)
      { docObj.style.display = mode; 
        return true;
      }
      return false;
    }

    /* --------------------------------------------- */
    AJPHPlist.switchDisplay = function( docObj)
    { if (docObj!=undefined && docObj!=null)
      { docObj.style.display = (docObj.style.display=='none') ? 'block': 'none';
        return true;
      }
      return false;
    }

    /* --------------------------------------------- */
    AJPHPlist.switchPane = function( elementIdName, mode)  // argument 'mode' is optional
    { var dmode = (typeof(mode)!='undefined' && mode!=null) ? mode : 'switch';
      if (dmode == 'on'  || dmode == 1)  { dmode = 'block'; }
      if (dmode == 'off' || dmode == 0)  { dmode = 'none'; }

      if (dmode!='switch') { AJPHPlist.setDisplay( document.getElementById( elementIdName), dmode);}
      else                 { AJPHPlist.switchDisplay( document.getElementById( elementIdName)); }
    }

    /* --------------------------------------------- */
    AJPHPlist.switchPanesByString = function( patternOfIdName, mode)  // argument 'mode' is optional
    { var regPoin = new RegExp( patternOfIdName);
      var nodeObj = null;
      var elementList = document.getElementsByTagName('*');

      for (ecnt=0; ecnt<elementList.length; ecnt++ ) 
      { nodeObj = elementList[ecnt];
        if (nodeObj.id) 
        { if (nodeObj.id.match( regPoin)) 
          { AJPHPlist.switchPane( nodeObj.id, mode);
          }
        }
      }
    }

    /* --------------------------------------------- */
    AJPHPlist.setInnerHtml = function( elementIdName, message)
    { document.getElementById( elementIdName).innerHTML = message;
    }

    /* --------------------------------------------- */
    AJPHPlist.findFormParent = function( nodeObj)
    { if (typeof( nodeObj)=='undefined' || nodeObj==null || nodeObj.nodeType!=1)  
      { return null; 
      }
      var icnt=0;
      while ( nodeObj.tagName != 'FORM' && 
              typeof( nodeObj.parentNode) != 'undefined' && 
              nodeObj.parentNode != null && 
              nodeObj.parentNode.nodeType == 1
            ) 
      {
        nodeObj = nodeObj.parentNode;
      }
      if (nodeObj.tagName != 'FORM')  
      { return null; 
      }
      return nodeObj;
    }

    /* --------------------------------------------- */
    AJPHPlist.triggerLinkSubmit = function( anchObj, buttonName, buttonValue)
    { 
      var formObj = AJPHPlist.findFormParent( anchObj);
      if (formObj==null)  
      { alert(
          "A HTML problem occured: \n"
         +"Please position this submit link within the form \nto be submitted"
        );
        return false; 
      }
      AJPHPlist.SAVED.submitcmd    = buttonName;
      AJPHPlist.SAVED.submitcmdval = buttonValue;
      
      // a scripted form submission does not fire the onsubmit event, but this is critical
      if (document.createEvent)  // W3C DOM
      { var newEvnt = document.createEvent("HTMLEvents");
        newEvnt.initEvent( "submit", false, true);
        formObj.dispatchEvent( newEvnt);
      } 
      else if (document.fireEvent)  // MSIE
      { var newEvnt = document.createEventObject();
        newEvnt.cancelBubble = true;
        formObj.fireEvent( "onsubmit", newEvnt);
      }
      return true; 
    }

    /* --------------------------------------------- */
    AJPHPlist.customizeFormSubmit = function( formObj) 
    { 

      AJPHPlist.SAVED.formcnt = -1;
      for (fcnt=0; fcnt < document.forms.length; fcnt++)
      { if (formObj==document.forms[fcnt])
        { AJPHPlist.SAVED.formcnt = fcnt;
        }
      }
      if (AJPHPlist.SAVED.formcnt == -1) {
        alert( "The form you have submitted could not be found. \n"
              +"Please check your HTML code for a proper setup \n"
              +"with the <form ... > tag element. \n"
             );
        return false;
      }

      // delete all hidden 'temporary helper' input elements in this form
      hiddenList = formObj.getElementsByTagName('input');
      for (hcnt=0; hcnt < hiddenList.length; hcnt++) 
      { if ( hiddenList[hcnt].getAttribute('type')  == 'hidden' && 
             hiddenList[hcnt].getAttribute('ajphp') == 'temporary helper'
           ) {
            // might be problematic, better collect in an array and delete afterwards?
            formObj.removeChild( hiddenList[hcnt--]); // removed child changes count
        }
      }

      // retrieve which submit button was clicked, if any      
      var submitButton    = '';
      var submitButtonVal = '';
      var pseudoButton    = false;

      if (AJPHPlist.SAVED.submitcmd != '')
      { // a submit LINK was clicked, thus emulate the submit BUTTON
        pseudoButton    = true;
        submitButton    = AJPHPlist.SAVED.submitcmd;
        submitButtonVal = AJPHPlist.SAVED.submitcmdval;
      }
      else if (formObj.ajform.submitter.elm != null) 
      { // a real submit BUTTON was clicked
        // (currently this accesses the ajForms lib directly, better to chain the event handlers for the buttons)
        if (typeof( formObj.ajform.submitter.elm.name != 'undefined') && formObj.ajform.submitter.elm.name != null) 
        { submitButton = formObj.ajform.submitter.elm.name;
        }
      }
      else
      { // no submit button was clicked (MSIE, if return key was pressed in a text input field like 'email')
        pseudoButton    = true;
        submitButton    = AJPHPlist.CONFIG.defaultSubmit;
        submitButtonVal = AJPHPlist.CONFIG.defaultSubmitVal;
      }

      if (pseudoButton)
      { // create a hidden input element with name of submitButton and mark it as 'temporary helper'
        var hiddenInput = document.createElement('input');
        hiddenInput.setAttribute('name' ,  submitButton);
        hiddenInput.setAttribute('id'   ,  submitButton);
        hiddenInput.setAttribute('type' , 'hidden');
        hiddenInput.setAttribute('value',  submitButtonVal);
        hiddenInput.setAttribute('ajphp', 'temporary helper');
        formObj.appendChild( hiddenInput);
      }
      // store name of submit button
      AJPHPlist.SAVED.submitcmd = submitButton;

      /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
      // The following functionality is application dependant and has to 
      // be customized for every form application

      // check email address for valid format 
      // PHPlist will do additional checks (e.g. johndoe@aol.xyz will be rejected)
      var address = formObj.email.value;
      if (!AJPHPlist.checkEmail(address))   return false;


      // replace the requested page in action url if necessary (p=subscribe or p=unsubscribe)
      var actionurl = formObj.action;
      actionurl.match( /(.*?[?&]p=)(.*?)(&.+)*$/ );
      if (RegExp.$2 != submitButton)
      { actionurl = RegExp.$1 + submitButton + RegExp.$3;
      }
      formObj.action = actionurl;


      // the lists to subscribe to or unsubscribe from
      // <input  type="checkbox"  name="list[2]"  value="signup">
      // <input  type="checkbox"  name="list[2]"  value="signoff">
      subscribeLists = formObj.getElementsByTagName('input');
      for (hcnt=0; hcnt < subscribeLists.length; hcnt++ ) 
      { var hname = subscribeLists[hcnt].name;
        if (hname.match( /list\[\d+\]/i ))
        { 
          if (subscribeLists[hcnt].type=='checkbox' || subscribeLists[hcnt].type=='radio') 
          { if (!subscribeLists[hcnt].checked)  continue;
          } 
          subscribeLists[hcnt].value = (submitButton=='subscribe') ? 'signup' : 'signoff';
        }
      }
      /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

      return true;
    }

    /* --------------------------------------------- */
    AJPHPlist.resultHandler = function( subscribeResultText , statusCode , statusMessage) 
    {
      var formObj = document.forms[AJPHPlist.SAVED.formcnt];

      var submitcommand = AJPHPlist.SAVED.submitcmd;
      AJPHPlist.SAVED.submitcmd = "";  // reset for use with next form submission

      if( statusCode != AJForm.STATUS['SUCCESS'] ) 
      { // AJFORM failed. 
        // alert("Status Code: "+statusCode+"\n"+statusMessage+"\nRequested:\n"+formObj.action );
        return true;  // submit form on the standard way (does not use ajForm)
      }
      else 
      { // AJFORM succeeded.
        /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
        // The following functionality is application dependant and has to 
        // be customized for every form application

        // quick hack to substitude rmtsubscribe.php
        var rcode;
        if (subscribeResultText.match(/Your email has been added to our system/))
        { rcode = 1;
        }
        else if (subscribeResultText.match(/You have been unsubscribed/))
        { rcode = 2;
        }
        else
        { if (submitcommand == 'subscribe') 
          { rcode = 101;
          }
          else if (submitcommand == 'unsubscribe') 
          { rcode = 102;
          }
          else
          { rcode = -1;
          }
        }

        switch (rcode)
        { case 1: 
              showSubscribeSuccess( formObj, subscribeResultText);
              break;
          case 101: 
              showSubscribeFailure( formObj, subscribeResultText);
              break;

          case 2: 
              showUnsubscribeSuccess( formObj, subscribeResultText);
              break;
          case 102: 
              showUnsubscribeFailure( formObj, subscribeResultText);
              break;

          default:
              alert("An unkown result code was found. ajPHPlist will display the subscribe error message.");
              showSubscribeFailure( formObj, subscribeResultText);
              break;
        }
        /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
      }
      return false;
    }

    /* --------------------------------------------- */
    // functions to export (use outside this module)
    function submitLink( anchObj, buttonName, buttonValue)
    { return AJPHPlist.triggerLinkSubmit( anchObj, buttonName, buttonValue)
    }
    function preProcess( formObj) 
    { return AJPHPlist.customizeFormSubmit( formObj);
    }
    function handleReturnResult( subscribeResultText, statusCode, statusMessage) 
    { return AJPHPlist.resultHandler( subscribeResultText, statusCode, statusMessage);
    }
    function switchPane( elementIdName, mode)  // argument mode is optional
    { return AJPHPlist.switchPane( elementIdName, mode);
    }
    function switchPanesByString( patternOfIdName, mode)  // argument mode is optional
    { return AJPHPlist.switchPanesByString( patternOfIdName, mode);
    }
    function setInnerHtml( elementIdName, message)
    { return AJPHPlist.setInnerHtml( elementIdName, message);
    }
    /* --------------------------------------------- */



