/**
 * ContentAddModuleController.js
 * Define the ContentAddModuleController class/prototype
 *
 * $Revision: 1.23.2.1 $
 * $Date: 2010/06/10 13:52:28 $
 * Last edited by: $Author: jauldrid $
 */
ContentAddModuleController = function( oOptions )
{
  if( ContentAddModuleController.instanceIsOpen === true )
  {
    this.init = function(){};
    return;
  }

  this.init = function( oOptions )
  {
    ContentAddModuleController.instanceIsOpen = true;

    /* Modules */
    this.i = 0;
    this.oModules = new Object();                 /* Associative Array of Modules */
    this.oModuleTabs = new Object();              /* Associative Array of Tabs */
    this.iModuleCount = 0;                        /* Number of Modules */
    this.sModuleIdPrefix = 'quickAddSection_';    /* Prefix for Module Containers in a bundle */
    this.iGroupCount = 0;
    this.oModuleGroups = new Object();
    this.oModuleTabBars = new Object();
    this.iTabBarCount = 0;
    this.aDeleteStack = new Array();

    /* UI Objects */
    this.oModalContainer = null;                  /* Container for Dialog */
    this.oControlContainer = null;                /* Container for Cancel, Previous/Next, Save */
    this.oTabContainer = null;                    /* Container for Tabs */
    this.oFormArea = null;                        /* Container for Mdoal Modules */
    this.oMessageArea = null;                     /* Container for Message Area */
    this.oNextButton = null;                      /* Next Button */
    this.oPreviousButton = null;                  /* Previous Button */
    this.oSaveButton = null;                      /* Save Button */
    this.sSaveButtonLabel = 'Publish';               /* Label for Save Button */
    this.sTmpSaveButtonLabel = '';

    /* Current State */
    this.sCurrentModuleKey = null;          /* Index of the Module currently being displayed */
    this.bControlsDisabled = false;          /* Are controls (Tabs, next/previous, Save) disabled */
    this.oQueuedCallback = null;            /* Function to call after animation of the slides */
    this.oLastFetchOptions = new Object();
    this.sCurrentTabBarKey = null;
    this.oBackupObjects = new Object();
    this.bModal = true;
    this.oWindowContext;
    this.bCloseOpeningWindow = false;
    this.callbacks = new ContentAddModuleController.callbackManager();
		this.oInitOptions = {};									/*Options passed into create Content add - might be needed to break out into fullscreen*/

		//check if we need to open a new window
		oOptions = this._checkForNewWindow( oOptions );

    if( this.bNewWindow )
    {
      this._launchIntoFullWindow( oOptions );
    }
    else
    {
			//store the options so if we breakout to a new window later - we keep everything
			jQuery.extend( true, this.oInitOptions, oOptions );
			//parse the options
			oOptions = this._parseOptions( oOptions );

      if( this.bCloseOpeningWindow && window.opener )
      {
        this.oWindowContext = window.opener;
        while( this.oWindowContext.opener )
        {
          this.oWindowContext = this.oWindowContext.opener;
        }
        window.opener.close();
      }
      if( !this.oWindowContext )
      {
        if( this.bModal )
        {
          this.oWindowContext = window;
        }
        else
        {
          this.oWindowContext = window.opener;
        }
      }

      /* Setup Display */
      this._populateBackupObjects();
      this._buildModalContainer();
      this._drawTabArea();
      this._drawFormArea();
      this._drawControlArea();
      this._disableControls();
      this._hideControls();
      this._clearCustomEvents();
      this._registerEvents();

      $.ajaxSetup( { cache:true } );
      /* Fetch Module Bundle */
      $.ajaxSetup( { cache:true } );
      this._fetchModuleBundle( null, true, 0, null, oOptions );
    }

    window.jQuery( document ).unbind( 'LaunchSeeAlsoAdvanced' ).bind( 'LaunchSeeAlsoAdvanced', function( oEvent, oData )
    {
      var aUrn, sObjectType, nObjectId, sAddSeeAlsoUrl;
      if( oData.bSuccess )
      {
        aUrn = oData.object.sURN.split( ':' );
        sObjectType = aUrn[2];
        nObjectId = aUrn[3];
        sAddSeeAlsoUrl = '/workflow/setupSeeAlsoInteractiveWorkflow.html?objectType=' + sObjectType + '&objectId=' + nObjectId + '&attachOnSave=yes&fetchSeeAlsos=yes';
        window.open( sAddSeeAlsoUrl );
      }
    });
  };

  this._launchIntoFullWindow = function( oOptions )
  {
    var oForm = $( document.createElement( 'form' ) ).attr( 'action', '/addStuffFullScreen.html' ).attr( 'target', '_blank' ).attr( 'method', 'post' );
    var oField = $( document.createElement( 'input' ) ).attr( 'type', 'hidden' ).attr( 'name', 'oOptions' ).val( JSON.stringify( oOptions  ) );
    oForm.append( oField );
    $( 'body' ).append( oForm );
    oForm.submit();
    oForm.empty().remove();
    ContentAddModuleController.instanceIsOpen = false;
  };

	this._checkForNewWindow = function( oOptions )
	{
    if( typeof oOptions === 'object' && oOptions != null )
    {
      this.bNewWindow = false;
      if( typeof oOptions.bNewWindow === 'boolean' )
      {
        this.bNewWindow = oOptions.bNewWindow;
        delete oOptions.bNewWindow;
      }
		}
		else
		{
			oOptions = {};
		}
		return oOptions;

	}
  this._parseOptions = function( oOptions )
  {
    if( typeof oOptions === 'object' && oOptions != null )
    {
			this.sModalTitle = 'Add Stuff';
			if( typeof oOptions.sModalTitle === 'string' && oOptions.sModalTitle != '' )
			{
				this.sModalTitle = oOptions.sModalTitle;
				delete oOptions.sModalTitle;
			}

			this._sInitialModulesURL        = '/addStuff.html';
			if( typeof oOptions.sURL === 'string' && oOptions.sURL != '' )
			{
				this._sInitialModulesURL = oOptions.sURL;
				delete oOptions.sURL;
			}

			if( typeof oOptions.bModal === 'boolean' )
			{
				this.bModal = oOptions.bModal;
				delete oOptions.bModal;
			}

			if( typeof oOptions.bCloseOpeningWindow === 'boolean' )
			{
				this.bCloseOpeningWindow = oOptions.bCloseOpeningWindow;
			}

			if( typeof oOptions.oEventTriggers === 'object' && oOptions.oEventTriggers !== null )
			{
				var callbackTypes = [ 'success', 'error' ], ctIndex, currentCallbackType, currentEventTriggerOption, currentIndex;
				for( ctIndex in callbackTypes )
				{
					currentCallbackType = callbackTypes[ ctIndex ];
					if( typeof oOptions.oEventTriggers[currentCallbackType] === 'object' && oOptions.oEventTriggers[currentCallbackType] !== null )
					{
						currentEventTriggerOption = oOptions.oEventTriggers[currentCallbackType];
						if( ( typeof currentEventTriggerOption.events === 'object' && typeof currentEventTriggerOption.events.length === 'number' ) )
						{
							this.callbacks.addEvent( currentEventTriggerOption.events, ContentAddModuleController.callbacks.callbackTypes[ currentCallbackType ] );
						}
						if( typeof currentEventTriggerOption.allowDefault === 'boolean' )
						{
							this.callbacks.bDoDefault[ currentCallbackType ] = currentEventTriggerOption.allowDefault;
						}
					}

				}
				delete oOptions.oEventTriggers;
			}
    }
    else
    {
      oOptions = {};
    }
    return oOptions;
  };

  /* UI Initialization ************************************************************************************/
  this._populateBackupObjects = function()
  {
    var aBackupNames = [ 'kwSearch', 'SearchWidgetWords' ];

    for( var x = 0; x < aBackupNames.length; x++ )
    {
        if( typeof window[ aBackupNames[ x ] ] != 'undefined' && window[ aBackupNames[ x ] ] != null )
        {
            this.oBackupObjects[ aBackupNames[ x ] ] = window[ aBackupNames[ x ] ];
        }
    }
  };

  this._buildModalContainer = function()
  {
    this.oModalContainer = $( document.createElement( 'div' ) );
    $( 'body' ).append( this.oModalContainer );
    if( this.bModal )
    {
      this.oModalContainer.dialog( {
        position: "center",
        title: this.sModalTitle,
        closeOnEscape: false,
        dialogClass: 'contentAdd',
        buttons: {
          "Cancel": function() {
            $(this).dialog("close");
          }
        }
      } ).dialog( 'open' );

      $( '.contentAdd' ).find( '.ui-dialog-titlebar-close' ).hide();
    }
    else
    {
      this.oModalContainer.attr( 'id', 'contentAdd-full' );
    }
  };

  /*
   * Create containers/buttons for Next/Previous Buttons, Tabs, and Save Button
   */
  this._drawTabArea = function()
  {
    /* Tabs */
    if( this.bModal )
    {
      this.oTabContainer = $( document.createElement( 'div' ) );
    }
    else
    {
      this.oTabContainer = $( document.createElement( 'div' ) );
    }

    this.aDeleteStack.push( this.oTabContainer );
    this.oModalContainer.append( this.oTabContainer );
  };

  this._appendTabBar = function()
  {
    var oTabBar = $( document.createElement( 'div' ) ).addClass( 'ui-tabs-nav' ).hide();
    this.oModuleTabBars[ this.iTabBarCount ] = oTabBar;
    this.oTabContainer.append( this.oModuleTabBars[ this.iTabBarCount++ ] );
  };

  this._drawControlArea = function()
  {
    /* Cancel */
    this.oCancelButton = $( document.createElement( 'button' ) ).addClass( 'cancelButton' ).text( 'Cancel' );
    this.aDeleteStack.push( this.oCancelButton );

    /* Next */
    this.oNextButton = $( document.createElement( 'button' ) ).addClass( 'nextButton' ).text( ">" );
    this.aDeleteStack.push( this.oNextButton );

    /* Previous */
    this.oPreviousButton = $( document.createElement( 'button' ) ).addClass( 'previousButton' ).text( "<" );
    this.aDeleteStack.push( this.oPreviousButton );

    this.oCustomControlContainer = $( document.createElement( 'span' ) );

    this.oControlContainer = $( '.contentAdd' ).find('.ui-dialog-buttonpane' ).empty().addClass( 'moduleButtons' ).append( this.oPreviousButton ).append( this.oCancelButton ).append( this.oCustomControlContainer ).append( this.oNextButton );

    this.aDeleteStack.push( this.oControlContainer );
    $( this.oModalContainer ).append( this.oControlContainer );
  };

  this._drawFormArea = function()
  {
    this.oFormArea = $( document.createElement( 'div' ) ).addClass( 'formArea' );
    this.aDeleteStack.push( this.oFormArea );
    this.oModalContainer.append( this.oFormArea );
  };

  /* Handlers ************************************************************************************/
  this._registerEvents = function()
  {
    this.oNextButton.click( this._nextButtonHandler() );
    this.oPreviousButton.click( this._previousButtonHandler() );
    this.oCancelButton.click( this._cancelButtonHandler() );
    /*Register Custom Events*/
    $( document ).bind( 'CAMC.save',  this._saveButtonHandler() );
  };

  this._clearCustomEvents = function()
  {
    $( document ).unbind( 'CAMC' );
  };

  this._nextButtonHandler = function()
  {
    var oThis = this;
    return ( function()
    {
      if( !oThis._areControlsDisabled() )
      {
        oThis._loadModule( oThis._getNextModuleKey() );
      }
    } );
  };

  this._previousButtonHandler = function()
  {
    var oThis = this;
    return ( function()
    {
      if( !oThis._areControlsDisabled() )
      {
        oThis._loadModule( oThis._getPreviousModuleKey() );
      }
    } );
  };

  this._cancelButtonHandler = function()
  {
    var oThis = this;
    return ( function()
    {
      oThis._closeModalContainer();
    } );
  };

  this._tabHandler = function( oModule )
  {
    var oThis = this;
    return (  function()
    {
      if( !oThis._areControlsDisabled() )
      {
        oThis._loadModule( oModule.getName() );
      }
    } );
  };

  /* UI Manipulation ************************************************************************************/
  this._hideControls = function()
  {
    this.oNextButton.hide();
    this.oPreviousButton.hide();
    this.oCancelButton.hide();
  };

  this._showControls = function()
  {
    if( parseInt( this.sCurrentModuleKey ) == 0 )
    {
      this.oPreviousButton.hide();
    }
    else
    {
      this.oPreviousButton.show();
    }

    if( parseInt( this.sCurrentModuleKey ) == ( this.iModuleCount - 1 ) )
    {
      this.oNextButton.hide();
    }
    else
    {
      this.oNextButton.show();
    }

    var oModuleGroup = this.oModuleGroups[ this.oModules[ this.sCurrentModuleKey ].getGroupId() ];

    this.oCancelButton.show();
  };

  this._disableControls = function()
  {
    this.bControlsDisabled = true;
  };

  this._enableControls = function()
  {
    this.bControlsDisabled = false;
  };

  this._areControlsDisabled = function()
  {
    return this.bControlsDisabled;
  };

  this._toggleSaveSuspend = function( oButton )
  {
    var SuspendedSaveButtonClass = 'SuspendedSaveButton';
    if( typeof oButton === 'object' && oButton !== null )
    {
      this._disableControls();
      this.sTmpSaveButtonLabel = $( oButton ).html();
      $( oButton ).html( '<img src="/images/loadingsmall.gif" /> Saving...' ).toggleClass( SuspendedSaveButtonClass );
    }
    else
    {
      this._enableControls();
      $( '.' + SuspendedSaveButtonClass ).html( this.sTmpSaveButtonLabel ).toggleClass( SuspendedSaveButtonClass );
    }
  };

  this._doModuleValidation = function()
  {
    var bResult = false;
    this._removeAllErrorMessages();
    if( this._validateModules() )
    {
      if( this._displayPromptModules() )
      {
        bResult = true;
      }
      else
      {
        bResult = false;
      }
    }
    else
    {
      bResult = false;
    }
    return bResult;
  };

  this._saveButtonHandler = function()
  {
    var oThis = this;
    return ( function()
    {
      if( !oThis._areControlsDisabled() )
      {
        oThis._removeAllErrorMessages();
        var oModuleGroup = oThis.oModuleGroups[ oThis.oModules[ oThis.sCurrentModuleKey ].getGroupId() ];
        if( oModuleGroup.getButtonAction() == 'submit' )
        {
          if( oThis._validateModules() )
          {
            if( oThis._displayPromptModules() )
            {
              $( window.document.forms[ oModuleGroup.getFormName() ] ).attr( 'target', '_blank' ).submit();
              oThis._closeModalContainer();
            }
          }
        }
        else if( oModuleGroup.getButtonAction() == 'ajax' )
        {
          if( oThis._validateModules() )
          {
            if( oThis._displayPromptModules() )
            {
              this.disabled = true;
              $( window.document.forms[ oModuleGroup.getFormName() ] ).ajaxSubmit();
              oThis._closeModalContainer();
            }
          }
        }
        else
        {
          var oReturn = window[ oModuleGroup.getActionFunction() ]();
          //remove children
          oThis._removeModuleGroupChildren( oModuleGroup.getId() );
          oThis._fetchModuleBundle( oReturn.sURL, true, null, oModuleGroup.getId(), oReturn.oOptions );
        }
      }
    } );
  };

  this._loadChildModule = function( sURL, oOptions )
  {
    var oModuleGroup = this.oModuleGroups[ this.oModules[ this.sCurrentModuleKey ].getGroupId() ];
    //remove children
    this._removeModuleGroupChildren( oModuleGroup.getId() );
    this._fetchModuleBundle( sURL, true, null, oModuleGroup.getId(), oOptions );
  };

	/*
		Restart a content add to begining - and load bundle with given options
	*/
  this._restartWithParams = function( oOptions )
  {
		this.oCustomControlContainer.empty();
		this._hideControls();
    this._removeModuleGroupChildren( null );
		this.sCurrentTabBarKey = null;
		this.sCurrentModuleKey = null;
    this._fetchModuleBundle( '', true, null, null, oOptions );
  };

  this._handlePrompt = function( sText, oModule )
  {
    var displayObject = $( document.createElement( 'h2' ) ).text( sText ).addClass( 'ui-state-highlight' ).addClass( 'promptMessage' );
    oModule.getView().prepend( displayObject );
  };

  this._handleErrorMessages = function( aErrorInfo, oModule )
  {
    var sText = '';
    for( var x = 0; x < aErrorInfo.length; x++ )
    {
      aErrorInfo[ x ].displayObject = $( document.createElement( 'h2' ) ).text( aErrorInfo[ x ].message ).addClass( 'ui-state-error' );
      oModule.getView().prepend( aErrorInfo[ x ].displayObject );
      if(typeof aErrorInfo[ x ].object !== 'undefined' && aErrorInfo[ x ].object !== null)
      {
        $( aErrorInfo[ x ].object ).parent().addClass( 'ui-state-error' );
        $( aErrorInfo[ x ].object ).bind( 'click.removeErrorMessage', this._removeErrorMessage( aErrorInfo[ x ] ) ).focus;
      }
    }
  };

  this._removeAllErrorMessages = function()
  {
    this.oModalContainer.find( 'h2.ui-state-highlight' ).remove();
    this.oModalContainer.find( 'h2.ui-state-error' ).remove();
    this.oModalContainer.removeClass( 'ui-state-error' );
  };

  this._removeErrorMessage = function( oErrorInfo )
  {
    var oThis = this;
    return ( function()
    {
      oErrorInfo.displayObject.remove();
      $( oErrorInfo.object ).parent().removeClass( 'ui-state-error' );
      $( oErrorInfo.object ).unbind( 'click.removeErrorMessage' );
    } );
  };

  this.addModule = function( oModule )
  {
    this.oModules[ oModule.getName() ] = oModule;
    this.oModules[ oModule.getName() ].getView().addClass( 'processed' );
    this.iModuleCount++;
    this._addModuleTab( oModule );
  };

  this._addModuleTab = function( oModule )
  {
    var bFocal = this.oModuleGroups[ oModule.getGroupId() ].getIsFocal();
    var oModuleTab = new ModuleTab();
    oModuleTab.setView( $( document.createElement( 'button' ) ).click( this._tabHandler( oModule ) ) );
    oModuleTab.setRequired( oModule.isRequired() );
    oModuleTab.setTitle( oModule.getTitle() );
    oModuleTab.setName( oModule.getName() );

    if( this.iTabBarCount == 0 || bFocal )
    {
      this._appendTabBar();
      this.oModuleGroups[ oModule.getGroupId() ].setIsFocal( false );
    }
    var sTabBarKey = new String( this.iTabBarCount - 1 );
    var oTabBar = this.oModuleTabBars[ sTabBarKey ];
    oModuleTab.setTabBarName( sTabBarKey );
    if( typeof this.oModuleTabs[ oModule.getName() ] == 'undefined' )
    {
      this.oModuleTabs[ oModule.getName() ] = oModuleTab;
      oTabBar.append( this.oModuleTabs[ oModule.getName() ].getView() );
    }
    else if( bFocal )
    {
      this.oModuleTabs[ oModule.getName() ].getView().remove();
      this.oModuleTabs[ oModule.getName() ] = oModuleTab;
      oTabBar.append( this.oModuleTabs[ oModule.getName() ].getView() );
    }
    else
    {
      var oldTab = this.oModuleTabs[ oModule.getName() ].getView();
      this.oModuleTabs[ oModule.getName() ] = oModuleTab;
      oldTab.replaceWith( this.oModuleTabs[ oModule.getName() ].getView() );
    }
  };

  this._displayLoadingTab = function( sText, sPlaceHolderKey )
  {
    var oModuleTab = new ModuleTab();
    oModuleTab.setView( $( document.createElement( 'button' ) ) );
    oModuleTab.setTitle( sText );
    var oLoadingImage = document.createElement( 'img' );
    oLoadingImage.src = '/images/loadingsmall.gif';
    oModuleTab.getView().prepend( oLoadingImage );

    if( sPlaceHolderKey in this.oModuleTabs )
    {
      this.oModuleTabs[ sPlaceHolderKey ].getView().remove();
      delete this.oModuleTabs[ sPlaceHolderKey ];
    }
    this.oModuleTabs[ sPlaceHolderKey ] = oModuleTab;
    if( this.iTabBarCount == 0 )
    {
      this._appendTabBar();
    }
    var oTabBar = this.oModuleTabBars[ new String( this.iTabBarCount - 1 ) ];
    oTabBar.append( this.oModuleTabs[ sPlaceHolderKey ].getView() ).show();
  };

  this._highlightTab = function( sCurrentTab )
  {
    if( typeof this.oModuleTabs[ sCurrentTab ] != 'undefined' && this.oModuleTabs[ sCurrentTab ] != null )
    {
      this.oTabContainer.find( 'button' ).removeClass( 'selected' );
      this.oModuleTabs[ sCurrentTab ].getView().addClass( 'selected' );;
    }
  };

  this._updateTabBars = function( sKey )
  {
    var sDestinationTabBarKey = this.oModuleTabs[ sKey ].getTabBarName();
    var sCurrentTabBarKey = this.oModuleTabs[ this.sCurrentModuleKey ].getTabBarName();
    if( parseInt( sDestinationTabBarKey ) > parseInt( sCurrentTabBarKey ) )
    {
      this.oModuleTabBars[ sCurrentTabBarKey ].hide();
      this.oModuleTabBars[ sDestinationTabBarKey ].show();
    }
    else if( parseInt( sDestinationTabBarKey ) < parseInt( sCurrentTabBarKey ) )
    {
      this.oModuleTabBars[ sCurrentTabBarKey ].hide();
      this.oModuleTabBars[ sDestinationTabBarKey ].show();
    }
  };

  this._loadModule = function( sKey )
  {
    if( sKey != null && !isNaN( sKey )  )
    {
      if( this.sCurrentModuleKey != null && !isNaN( this.sCurrentModuleKey ) )
      {
        if( sKey == this.sCurrentModuleKey )
        {
          this._executeQueuedCallbacks();
          return true;
        }
        else if( this.iModuleCount == 1 )
        {
           sKey = 0;
        }
        else if( sKey < 0 )
        {
          sKey = ( this.iModuleCount - 1 );
        }
        else if( sKey >= this.iModuleCount )
        {
           sKey = 0;
        }

        this.oModules[ sKey ].clearPrompt();
        this._setupGroup( sKey );
        if( parseInt( sKey ) > parseInt( this.sCurrentModuleKey ) )
        {
          this._disableControls();
          this._updateTabBars( sKey );
          this._highlightTab( sKey );
          this.oModules[ this.sCurrentModuleKey ].getView().hide()
          this.oModules[ sKey ].getView().show();
          this.sCurrentModuleKey = sKey;
          this._enableControls();
          this._showControls();
          return true;
        }
        else if( parseInt( sKey ) < parseInt( this.sCurrentModuleKey ) )
        {
          this._disableControls();
          this._updateTabBars( sKey );
          this._highlightTab( sKey );
          this.oModules[ this.sCurrentModuleKey ].getView().hide()
          this.oModules[ sKey ].getView().show();
          this.sCurrentModuleKey = sKey;
          this._enableControls();
          this._showControls();
          return true;
        }
        else
        {
          this._setupGroup( sKey );
          this._loadModule( sKey );
          return true;
        }
      }
      else
      {
      //  this.sCurrentModuleKey = sKey;
        this._setupGroup( sKey );
        this.oModules[ sKey ].clearPrompt();
        this._highlightTab( sKey );
        this.oModules[ sKey ].getView().fadeIn( 500, this._enableControls() );
        this.sCurrentModuleKey = sKey;
        this._showControls();
      }

      this.sCurrentModuleKey = sKey;
    }
  };

  this._setupGroup = function( sModuleKey )
  {
    var oModuleGroup = this.oModuleGroups[ this.oModules[ sModuleKey ].getGroupId() ];
    var aButtons = oModuleGroup.getButtons();
    this.oCustomControlContainer.empty();

    var x, oControlOptions, oProcessingOptions, sActionType, sBindType, bShowInToolbar, sSelector, sLabel, oHTMLObject;
    for( x = 0; x < aButtons.length; x++ )
    {
      oControlOptions              = aButtons[ x ].oControlOptions;
      oProcessingOptions           = aButtons[ x ].oProcessingOptions;

      sActionType           = oControlOptions.sActionType;
      sBindType             = oControlOptions.sBindType || 'click';
      bShowInToolbar        = ( oControlOptions.bShowInToolbar == "1" );
      sSelector             = oControlOptions.sSelector;
      sLabel                = oControlOptions.sLabel;

      oHTMLObject = null;

      if( typeof sActionType != 'undefined' && sActionType != null )
      {

        if( bShowInToolbar == "1" )
        {
          oHTMLObject = $( document.createElement( 'button' ) ).text( sLabel );
          sBindType = 'click';
          this.oCustomControlContainer.append( oHTMLObject );
        }
        else if( sSelector != '' )
        {
          oHTMLObject = this.oModalContainer.find( sSelector );
        }

        switch( sActionType.toUpperCase() )
        {
          case 'LOAD_CHILD_MODULE':
            oHTMLObject.bind( sBindType, this._generate_LOAD_CHILD_MODULE( oProcessingOptions ) );
            break;
          case 'FUNCTION':
            oHTMLObject.bind( sBindType, this._generate_FUNCTION( oProcessingOptions ) );
            break;
          case 'SUBMIT':
            oHTMLObject.bind( sBindType, this._generate_SUBMIT( oProcessingOptions, oModuleGroup.getFormName() ) );
            break;
        }
      }
    }
  };

  this._slideTransitionForward = function( iDestination, iSpeed )
  {
      var oThis = this;
      return ( function()
      {
        var ooThis = oThis;
        if( oThis.sCurrentModuleKey < iDestination )
        {
          return ( function()
          {
            ooThis.oModules[ ooThis.sCurrentModuleKey ].getView().hide( "slide", { direction: "left" }, iSpeed );
            ooThis._updateTabBars( ooThis.sCurrentModuleKey + 1 );
            ooThis.sCurrentModuleKey++;
            ooThis._highlightTab( ooThis.sCurrentModuleKey );
            ooThis.oModules[ ooThis.sCurrentModuleKey ].getView().show( "slide", { direction: "right" }, iSpeed, ooThis._slideTransitionForward( iDestination, ( iSpeed + ( ooThis.fAccelerationFactor * iSpeed ) ) ) );
          } );
        }
        else
        {
          return ( function()
          {
            oThis._enableControls();
            oThis._showControls();
            oThis._executeQueuedCallbacks();
          } );
        }
      } )();
  };

  this._slideTransitionBackward = function( iDestination, iSpeed )
  {
      var oThis = this;
      return ( function()
      {
        var ooThis = oThis;
        if( oThis.sCurrentModuleKey > iDestination )
        {
          return ( function()
          {
            ooThis.oModules[ ooThis.sCurrentModuleKey ].getView().hide( "slide", { direction: "right" }, iSpeed );
            ooThis._updateTabBars( ooThis.sCurrentModuleKey - 1);
            ooThis.sCurrentModuleKey--;
            ooThis._highlightTab( ooThis.sCurrentModuleKey );
            ooThis.oModules[ ooThis.sCurrentModuleKey ].getView().show( "slide", { direction: "left" }, iSpeed, ooThis._slideTransitionBackward( iDestination, ( iSpeed + ( ooThis.fAccelerationFactor * iSpeed ) ) ) );
          } );
        }
        else
        {
          return ( function()
          {
            oThis._enableControls();
            oThis._showControls();
            oThis._executeQueuedCallbacks();
          } );
        }
      } )();
  };

  /* State ************************************************************************************/
  this._getNextModuleKey = function()
  {
    return ( parseInt( this.sCurrentModuleKey ) + 1 );
  };

  this._getPreviousModuleKey = function()
  {
    return ( parseInt( this.sCurrentModuleKey ) - 1 );
  };

  this._executeQueuedCallbacks = function()
  {
    if( typeof this.oQueuedCallback == 'function' && this.oQueuedCallback != null )
    {
      this.oQueuedCallback();
      this.oQueuedCallback = null;
    }
  };

  this._validateModules = function()
  {
    var sUnValidatedKey = null;
    for( var x in this.oModules )
    {
      this.oModules[ x ].validate();
      if( !this.oModules[ x ].isValidated() )
      {
        sUnValidatedKey = this.oModules[ x ].getName();
        break;
      }
    }

    if( sUnValidatedKey != null )
    {
      this._handleErrorMessages( this.oModules[ sUnValidatedKey ].getErrorMessages(), this.oModules[ sUnValidatedKey ] );
      this._loadModule( sUnValidatedKey );
      return false;
    }
    else
    {
      return true;
    }
  };

  this._displayPromptModules = function()
  {
    var sPromptKey = null;
    for( var x in this.oModules )
    {
      if( this.oModules[ x ].isPrompt() )
      {
        sPromptKey = this.oModules[ x ].getName();
        break;
      }
    }

    if( sPromptKey != null )
    {
      this._handlePrompt( this.oModules[ sPromptKey ].getPromptMessage(), this.oModules[ sPromptKey ] );
      this._loadModule( sPromptKey );
      return false;
    }
    else
    {
      return true;
    }
  };

  this._getModuleGroupDescendantIds = function( iModuleGroupId )
  {
    var aDescendantIds = new Array();
    for( var x in this.oModuleGroups )
    {
      if( this.oModuleGroups[ x ].getParentId() == iModuleGroupId )
      {
        aDescendantIds.push( this.oModuleGroups[ x ].getId() );
        aDescendantIds = aDescendantIds.concat(  this._getModuleGroupDescendantIds( this.oModuleGroups[ x ].getId() ) );
      }
    }
    return aDescendantIds;
  };

  this._removeModuleGroupChildren = function( iModuleGroupId )
  {
    var aDescendantIds = this._getModuleGroupDescendantIds( iModuleGroupId );
    var iGroupId = null;
    for( var x in this.oModules )
    {
      iGroupId = this.oModules[ x ].getGroupId();
      if( jQuery.inArray( iGroupId, aDescendantIds ) != -1 )
      {
        this.oModules[ x ].getView().remove();
        this.oModuleTabs[ x ].getView().remove();
        delete this.oModules[ x ];
        delete this.oModuleTabs[ x ];
        this.iModuleCount--;
      }
    }
    for( x = 0; x < aDescendantIds.length; x++ )
    {
      this.oFormArea.find( '.groupContainer' + this.oModuleGroups[ aDescendantIds[ x ] ].getId() ).empty().remove();
      delete this.oModuleGroups[ aDescendantIds[ x ] ];
      this.iGroupCount--;
    }

    for( x in this.oModuleTabBars )
    {
      if( this.oModuleTabBars[ x ].children().length == 0)
      {
        this.oModuleTabBars[ x ].remove();
        delete this.oModuleTabBars[ x ];
        this.iTabBarCount--;
      }
    }
  };

  /* Data ************************************************************************************/
  this._fetchModuleBundle = function ( sURL, bDisplayOnLoad, sFirstModuleKey, nParentGroupId, oOptions )
  {
    var oThis = this;
    if( typeof sURL == 'undefined' || sURL == null || sURL == '' )
    {
      sURL = this._sInitialModulesURL;
    }

    if( typeof bDisplayOnLoad != 'boolean' || bDisplayOnLoad )
    {
      bDisplayOnLoad = true;
      this._disableControls();
    }

    if( typeof oOptions == 'undefined' || oOptions == null )
    {
      oOptions = new Object();
    }

    if( typeof sFirstModuleKey == 'undefined' || sFirstModuleKey == null || sFirstModuleKey == '' )
    {
      if( 'sFirstModuleKey' in oOptions  && typeof oOptions.sFirstModuleKey != 'undefined' && typeof oOptions.sFirstModuleKey != null )
      {
        sFirstModuleKey = oOptions.sFirstModuleKey;
      }
      else
      {
       sFirstModuleKey = this.iModuleCount;
      }
    }

    if( typeof nParentGroupId == 'undefined' || nParentGroupId == null || nParentGroupId == '' )
    {
      if( 'nParentGroupId' in oOptions && typeof oOptions.nParentGroupId != 'undefined' && typeof oOptions.nParentGroupId != null )
      {
        nParentGroupId = oOptions.nParentGroupId;
      }
      else
      {
        if( this.iGroupCount > 0 )
        {
          nParentGroupId = this.iGroupCount - 1;
        }
        else
        {
          nParentGroupId = '';
        }
      }
    }
    var oTemp = {
      sFirstModuleKey: sFirstModuleKey,
      nParentGroupId: nParentGroupId
    };
    if( typeof oOptions == 'undefined' )
    {
      oOptions = new Object();
    }
    jQuery.extend( true, oOptions, oTemp );
    this.oLastFetchOptions = oOptions;

    this._displayLoadingTab('', sFirstModuleKey );
    this._hideControls();
    $.post(
      sURL,
      ( function( oOptions )
      {
        var retval = {};
        var key;

        for( key in  oOptions )
        {
          if( typeof  oOptions[key] == 'object' )
          {
            retval[key] =  JSON.stringify( oOptions[key] );
          }
          else
          {
            retval[key] =  oOptions[key];
          }
        }
        return retval;
      }( oOptions ) ),
      function( sData )
      {
        var iModuleToLoad = null;
        if( bDisplayOnLoad )
        {
          iModuleToLoad = oThis.iModuleCount;
        }

        var oData = JSON.parse( sData );

				if( typeof oData.bSuccess === 'boolean' )
				{
					alert( "The following error occurred:\n" + oData.sMessage );
					oThis._closeModalContainer();
				}
				else
				{
					oThis._addBundleToDom( oData.page_data );
					var bRedirect = oThis._parseModuleBundle( oData );
					if( bDisplayOnLoad && !bRedirect)
					{
						oThis._loadModule( iModuleToLoad );
						oThis.enableButtonControllers();
					}
				}
      },
      'html'
    );
  };

  this.enableButtonControllers = function()
  {
    if( typeof window[ 'bContentAddContentTypesEnabled' ] != 'undefined' && window[ 'bContentAddContentTypesEnabled' ] != null )
    {
      window[ 'bContentAddContentTypesEnabled' ] = true;
    }
  };


  this._addBundleToDom = function( sHTML )
  {
    var oDiv = $( '<div></div>' ).addClass( 'stagingArea' );
    this.oFormArea.append( oDiv );
    oDiv.append( sHTML );
    vneOnload.trigger();
  };

  /*
   * The following functions get used asynchronosuly so we'll wrap them up and pass 'this' in
   */
  ( function( oThis )
  {
    oThis._closeModalContainer = function()
    {
      if( oThis.bModal )
      {
        try
        {
         oThis.oModalContainer.find('textarea.kwRichText').tinymce().remove();
        }
        catch( e ) {}

        for( var x = 0; x < oThis.aDeleteStack.length; x++ )
        {
          if( typeof oThis.aDeleteStack[ x ] == 'object' )
          {
            oThis.aDeleteStack[ x ].empty().remove();
          }
        }

        oThis.oModalContainer.dialog( 'destroy' ).remove();

       for( var x in oThis.oBackupObjects )
        {
            window[ x ] = oThis.oBackupObjects[ x ];
        }

        /*Unregister Custom Events*/
        oThis._clearCustomEvents();
				ContentAddModuleController.instanceIsOpen = false;
      }
      else
      {
        if(( this.oWindowContext !== null ) &&
           ( typeof this.oWindowContext == 'object' ) &&
           ( typeof this.oWindowContext.focus == 'function' ))
        {
          this.oWindowContext.focus();
        }
				ContentAddModuleController.instanceIsOpen = false;
				window.close();
      }
    };

    oThis._onSuccess  = function( oData, sTextStatus )
    {
      if( typeof oData !== 'object' || oData === null || ( typeof oData.bSuccess !== 'boolean' && typeof oData.bRedirect !== 'boolean' ) )
      {
        oData = {
          bSuccess: false,
          sMessage: 'Server returned invalid data format'
        };
      }

			if( typeof oData.bRedirect === 'boolean' )
			{
				oThis._restartWithParams( oData.aParameters );
			}
      else if( ! oData.bSuccess )
      {
        oThis._onError( null, oData.sMessage, null );
      }
      else
      {
        oThis.callbacks.run( oData, ContentAddModuleController.callbacks.callbackTypes.success, oThis.oWindowContext );
        oThis._closeModalContainer();
      }
    };


    oThis._onError = function( oXMLHttpRequest, sTextStatus, oErrorThrown )
    {
      alert( sTextStatus );
      var oData = { bSuccess: false, sMessage: sTextStatus };
      oThis.callbacks.run( oData, ContentAddModuleController.callbacks.callbackTypes.error, oThis.oWindowContext );
      oThis._toggleSaveSuspend();
    };
  } )( this );


  this._generate_SUBMIT = function( oProcessingOptions, sFormName )
  {
    var oThis                 = this;

    var bValidation           = ( oProcessingOptions.bValidation == "1" );
    var bCloseAfterExecute    = true;
    var sFunctionName         =  oProcessingOptions.sFunctionName;
    var oFunctionOptions      = {};
    oFunctionOptions          = oProcessingOptions.oFunctionOptions || {};

    return ( function()
    {
      if( ! oThis._areControlsDisabled() )
      {
        if( ! bValidation || ( bValidation && oThis._doModuleValidation() ) )
        {
          var oOptions = null;
          if( typeof oFunctionOptions != 'undefined' && oFunctionOptions != null )
          {
            oOptions = oFunctionOptions;
          }

          if( ( typeof sFunctionName === 'undefined' || sFunctionName === null ) || ( window[ sFunctionName ]( oOptions ) ) )
          {
            oThis._toggleSaveSuspend( this );

            var oAjaxSubmitOptions = {
              success: oThis._onSuccess,
              error: oThis._onError,
              dataType: 'json'
            };
            $( window.document.forms[ sFormName ] ).ajaxSubmit( oAjaxSubmitOptions );
          }
        }
      }
    } );
  };

  this._generate_FUNCTION = function( oProcessingOptions )
  {
    var oThis              = this;

    var bValidation        = ( oProcessingOptions.bValidation == "1" );
    var bCloseAfterExecute = ( oProcessingOptions.bCloseAfterExecute == "1" );
    var sFunctionName      = oProcessingOptions.sFunctionName;
    var oFunctionOptions   = {};
    oFunctionOptions       = oProcessingOptions.oFunctionOptions || {};

    return  ( function()
    {
      if( !oThis._areControlsDisabled() )
      {
        if( !bValidation || ( bValidation && oThis._doModuleValidation() ) )
        {
          var oOptions = null;
          if( typeof oFunctionOptions != 'undefined' && oFunctionOptions != null )
          {
            oOptions = oFunctionOptions;
          }
          window[ sFunctionName ]( oOptions );
          if( bCloseAfterExecute == "1" )
          {
            oThis._closeModalContainer();
          }
        }
      }
    } );
  };

  this._generate_LOAD_CHILD_MODULE = function( oProcessingOptions )
  {
    var oThis              = this;

    var bValidation        = ( oProcessingOptions.bValidation == "1" );
    var bCloseAfterExecute = ( oProcessingOptions.bCloseAfterExecute == "1" );
    var sFunctionName      = oProcessingOptions.sFunctionName;
    var oFunctionOptions   = {};
    oFunctionOptions       = oProcessingOptions.oFunctionOptions || {};

    return  ( function()
    {
      if( !oThis._areControlsDisabled() )
      {
        if( !bValidation || ( bValidation && oThis._doModuleValidation() ) )
        {
          var oOptions = null;
          if( typeof oFunctionOptions != 'undefined' && oFunctionOptions != null )
          {
            oOptions = oFunctionOptions;
          }
          var oNewModuleOptions = window[ sFunctionName ]( oOptions );
          if( oNewModuleOptions !== null )
          {
            oThis._loadChildModule( oNewModuleOptions.sURL, oNewModuleOptions.oOptions );
            if( bCloseAfterExecute == "1" )
            {
              oThis._closeModalContainer();
            }
          }
        }
      }
    } );
  };

  this._generate_LAUNCH_FULLSCREEN = function( oProcessingOptions )
  {
    var oThis              = this;

    var bValidation        = ( oProcessingOptions.bValidation == "1" );
    var bCloseAfterExecute = true;
    var sFunctionName      =  oProcessingOptions.sFunctionName;
    var oFunctionOptions   = {};
    oFunctionOptions       = oProcessingOptions.oFunctionOptions || {};

    return ( function()
    {
      if( !oThis._areControlsDisabled() )
      {
        if( !bValidation || ( bValidation && oThis._doModuleValidation() ) )
        {
          //var oOptions = null;
					/*This assignment will cause oInitOptions to be updated as well since it done by reference, but that's ok because this content add will close*/
          var oOptions = oThis.oInitOptions;
          if( typeof oFunctionOptions != 'undefined' && oFunctionOptions != null )
          {
            //oOptions = oFunctionOptions;
						/*we are adding oFunctionOptions to oOptions*/
						jQuery.extend( true, oOptions, oFunctionOptions );
          }
          var oNewModuleOptions = window[ sFunctionName ]( oOptions );
          oThis._launchIntoFullWindow( oNewModuleOptions );
          oThis._closeModalContainer();
        }
      }
    } );
  };

  this._generate_SUCCESS_TRIGGER = function( oProcessingOptions )
  {
    var oThis = this;

    return function()
    {
      if( typeof window[oProcessingOptions.sFunctionName] === 'function' )
      {
        if( window[oProcessingOptions.sFunctionName]() )
        {
          oThis.callbacks.addEvent( oProcessingOptions.sTriggerName, ContentAddModuleController.callbacks.callbackTypes.success );
        }
        else
        {
          oThis.callbacks.removeEvent( oProcessingOptions.sTriggerName, ContentAddModuleController.callbacks.callbackTypes.success );
        }
      }
    };
  };

  this._parseModuleBundle = function( oData )
  {
    var oThis = this;
    var sFormName = null;
    var sParentGroup = null;
    var bShowButton = null;
    var sButtonLabel = null;
    var sButtonAction = null;
    var sActionFunction = null;
    var bFocalBundle = null;
    var sRedirectURL = null;
    var oRedirectOptions = new Object();
    var bRedirect = false;
    var aButtons = [];
    var instanceCount = 0;
    var bGoFullScreen = false;

    if( typeof oData.globalQuickAddMetaData != 'undefined' || oData.globalQuickAddMetaData != null )
    {
      var oGlobalOptions = oData.globalQuickAddMetaData;

      if( typeof oGlobalOptions.formName != 'undefined' && oGlobalOptions.formName != null )
      {
        sFormName = oGlobalOptions.formName;
      }

      if( typeof oGlobalOptions.action != 'undefined' && oGlobalOptions.action != null )
      {
        sButtonAction = oGlobalOptions.action;
      }

      if( typeof oGlobalOptions.showButton != 'undefined' && oGlobalOptions.showButton != null )
      {
        bShowButton = Boolean( parseInt( oGlobalOptions.showButton ) );
      }

      if( typeof oGlobalOptions.focalBundle != 'undefined' && oGlobalOptions.focalBundle != null )
      {
        bFocalBundle = Boolean( parseInt( oGlobalOptions.focalBundle ) );
      }

      if( typeof oGlobalOptions.actionFunction != 'undefined' && oGlobalOptions.actionFunction != null )
      {
        sActionFunction = oGlobalOptions.actionFunction;
      }

      if( typeof oGlobalOptions.parentGroupId != 'undefined' && oGlobalOptions.parentGroupId != null )
      {
        sParentGroup = oGlobalOptions.parentGroupId;
        if( sParentGroup == '' )
        {
          bFocalBundle = false;
        }
      }

      if( typeof oGlobalOptions.buttonLabel != 'undefined' && oGlobalOptions.buttonLabel != null )
      {
        sButtonLabel = oGlobalOptions.buttonLabel;
      }
      else
      {
        sButtonLabel = '';
      }

      if( typeof oGlobalOptions.aToolbarButtons != 'undefined' && oGlobalOptions.aToolbarButtons != null )
      {
        aButtons = oGlobalOptions.aToolbarButtons;
      }

      if( typeof oGlobalOptions.aModuleControls != 'undefined' && oGlobalOptions.aModuleControls != null )
      {
        aControls = oGlobalOptions.aModuleControls;

        var x, oControlOptions, oProcessingOptions, sActionType, sBindType, bShowInToolbar, sSelector, sLabel, oHTMLObject;
        for( x = 0; x < aControls.length; x++ )
        {
          oControlOptions              = aControls[ x ].oControlOptions;
          oProcessingOptions           = aControls[ x ].oProcessingOptions;

          sActionType           = oControlOptions.sActionType;
          sBindType             = oControlOptions.sBindType || 'click';
          bShowInToolbar        = ( oControlOptions.bShowInToolbar == "1" );
          sSelector             = oControlOptions.sSelector;
          sLabel                = oControlOptions.sLabel;

          oHTMLObject = null;

          if( typeof sActionType != 'undefined' && sActionType != null )
          {
            if( bShowInToolbar == "1" )
            {
              oHTMLObject = $( document.createElement( 'button' ) ).text( sLabel );
              sBindType = 'click';
              this.oCustomControlContainer.append( oHTMLObject );
            }
            else if( sSelector != '' )
            {
              oHTMLObject = this.oModalContainer.find( sSelector );
            }

            switch( sActionType.toUpperCase() )
            {
              case 'LOAD_CHILD_MODULE':
                oHTMLObject.bind( sBindType, oThis._generate_LOAD_CHILD_MODULE( oProcessingOptions ) );
                break;
              case 'FUNCTION':
                oHTMLObject.bind( sBindType, oThis._generate_FUNCTION( oProcessingOptions ) );
                break;
              case 'LAUNCH_FULL_SCREEN':
                if( oThis.bModal )
                {
                  oHTMLObject.bind( sBindType, oThis._generate_LAUNCH_FULLSCREEN( oProcessingOptions ) );
                }
                else
                {
                  oHTMLObject.bind( sBindType, oThis._generate_LOAD_CHILD_MODULE( oProcessingOptions ) );
                }

                break;
              case 'REGISTER_SUCCESS_TRIGGER':
                oHTMLObject.bind( sBindType, oThis._generate_SUCCESS_TRIGGER( oProcessingOptions ) );
                break;
            }
          }
        }
      }

      if( typeof oData.events != 'undefined' || oData.events != null )
      {
        var aEvents = oData.events;
        for( var x in oData.events )
        {
          $( oThis.oFormArea ).find( '[name="' + oData.events[ x ].object + '"]' ).bind( 'change ', function()
          {
            var oTempObject = new Object();
            oTempObject[ $( this ).val() ] = $( this ).find( ':selected' ).text();
            window[ oData.events[ x ].target ]( oTempObject, oData.events[ x ].params );
          } );
          var oObject =  $( oThis.oFormArea ).find( '[name="' + oData.events[ x ].object + '"]' );
          var oTempObject = {};
          oTempObject[ oObject.val() ] = oObject.find( ':selected' ).text();
          window[ oData.events[ x ].target ]( oTempObject, oData.events[ x ].params );
        }
      }
    }
    else
    {
      if( typeof oData.redirectParams != 'undefined' || oData.redirectParams != null )
      {
        var oRedirectParams = oData.redirectParams;
        if( typeof oRedirectParams.url != 'undefined' && oRedirectParams.url != null )
        {
          bRedirect = true;
          sRedirectURL = oRedirectParams.url;
        }

        if( typeof oRedirectParams.redirectOptions != 'undefined' && oRedirectParams.redirectOptions != null )
        {
          oRedirectOptions = oRedirectParams.redirectOptions;
        }

        if( typeof oRedirectParams.bGoFullScreen != 'undefined' && oRedirectParams.bGoFullScreen != null )
        {
          bGoFullScreen = oRedirectParams.bGoFullScreen;
        }

      }
    }

    $( oThis.oFormArea ).find( 'span.globalQuickAddMetaData' ).remove();
    if( ! bRedirect )
    {
      this.oLastFetchOptions = new Object();
      var oModuleGroup = new ContentAddGroup( this.iGroupCount, sParentGroup, sFormName, bShowButton, sButtonLabel, sButtonAction, sActionFunction, bFocalBundle, aButtons );
      this.oFormArea.find( 'div.stagingArea' ).removeClass( 'stagingArea' ).addClass( 'groupContainer' + oModuleGroup.getId() );
      oThis.oModuleGroups[ oThis.iGroupCount++ ] = oModuleGroup;
      //$( oThis.oFormArea ).find( '.quickAddModule' ).not( '.processed' ).each( function(i)
      var oStuff = $( oThis.oFormArea ).find( 'div.quickAddModule' ).not( 'div.processed' );
      var len = oStuff.length;
      for( var i = 0; i < len; i++ )
      {
        var oModule = new ContentAddModule();

        var oModuleOptions = oData.moduleOptions[ instanceCount++ ];

        if( typeof oModuleOptions.placeHolderKey != 'undefined' && oModuleOptions.placeHolderKey != null && oModuleOptions.placeHolderKey != '' )
        {
          oModule.setName( oModuleOptions.placeHolderKey );
        }
        else
        {
          oModule.setName( oThis.iModuleCount );
        }

        oModule.setGroupId( oModuleGroup.getId() );
       // oModule.setView( $( this ) );
        oModule.setView( $( oStuff[ i ] ) );
        oModule.setTitle( oModuleOptions.label );

        if( typeof oModuleOptions.required != 'undefined' && oModuleOptions.required != null && ( oModuleOptions.required.toLowerCase() == 'true' || oModuleOptions.required == '1' ) )
        {
          oModule.setRequired();
        }
        else if( typeof oModuleOptions.prompt != 'undefined' && oModuleOptions.prompt != null && ( oModuleOptions.prompt.toLowerCase() == "true" || oModuleOptions.prompt == '1' ) )
        {
          oModule.setPrompt();
          oModule.setPromptMessage( oModuleOptions.promptMessage );
        }

        if( typeof oModuleOptions.validationFunction != 'undefined' && oModuleOptions.validationFunction != null )
        {
          oModule.setValidationFunction( oModuleOptions.validationFunction );
        }

        oThis.addModule( oModule );
      }
      $( window.document.forms[ sFormName ] ).submit( function(){ return false; } );
    }
    else
    {
      /*
       * We want our new options ( oRedirectOptions ) to overwrite the options from the last fetch
       * (this.oLastFetchOptions ), but we don't want to change the contents of oLastFetchOptions yet
       */
      this.oFormArea.find( 'div.stagingArea' ).empty().remove();
      if( bGoFullScreen )
      {
				jQuery.extend( true, oRedirectOptions, this.oInitOptions );
        this._launchIntoFullWindow( oRedirectOptions );
        this._closeModalContainer();
      }
      else
      {
        this._fetchModuleBundle( sRedirectURL, true, null, null, oRedirectOptions);
      }
    }
    return bRedirect;
  };

  /* call constructor */
  this.init( oOptions );
};

/*Static property for all content adds to determine if another instance is already open.*/
ContentAddModuleController.instanceIsOpen = false;

ContentAddGroup = function( sId, sParentGroup, sFormName, bShowButton, sButtonLabel, sButtonAction, sActionFunction, bFocalBundle, aButtons )
{
  this.init = function( sId, sParentGroup, sFormName, bShowButton, sButtonLabel, sButtonAction, sActionFunction, bFocalBundle, aButtons )
  {
    this.sId = sId;
    if( typeof sParentGroup != 'undefined' && sParentGroup != null && sParentGroup != '' )
    {
      this.sParentId = sParentGroup;
    }
    else
    {
      this.sParentId = null;
    }
    this.sFormName = sFormName;
    this.sButtonLabel = sButtonLabel;
    this.sButtonAction = sButtonAction;
    if( typeof bShowButton == 'boolean' )
    {
      this.bShowButton = bShowButton
    }
    else
    {
      this.bShowButton = false;
    }

    if( typeof sActionFunction != 'undefined' && sActionFunction != null && sActionFunction != '' )
    {
      this.sActionFunction = sActionFunction;
    }
    else
    {
      this.sActionFunction = sActionFunction;
    }

    if( typeof aButtons != 'undefined' && aButtons != null && aButtons.length > 0 )
    {
      this.aButtons = aButtons;
    }
    else
    {
      this.aButtons = [];
    }

    if( typeof bFocalBundle == 'boolean' )
    {
      this.bFocalBundle = bFocalBundle
    }
    else
    {
      this.bFocalBundle = false;
    }
  };

  this.getId = function()
  {
    return this.sId;
  };

  this.getParentId = function()
  {
    return this.sParentId;
  };

  this.isButtonShown = function()
  {
    return this.bShowButton;
  };

  this.getFormName = function()
  {
    return this.sFormName;
  };

  this.getButtonLabel = function()
  {
    return this.sButtonLabel;
  };

  this.getButtonAction = function()
  {
    return this.sButtonAction;
  };

  this.getActionFunction = function()
  {
    return this.sActionFunction;
  };

  this.getButtons = function()
  {
    return this.aButtons;
  };

  this.setIsFocal = function( bFocal )
  {
    this.bFocalBundle = bFocal;
  };

  this.getIsFocal = function()
  {
    return this.bFocalBundle;
  };
  this.init( sId, sParentGroup, sFormName, bShowButton, sButtonLabel, sButtonAction, sActionFunction, bFocalBundle, aButtons );
};

/*
 * Static properties of ContentAddMOduleController to store some basic info about callbacks
 */
ContentAddModuleController.callbacks = {
  defaultEvents: {
      error: 'ContentAddError',
      success: 'ContentAddSuccess'
  },
  callbackTypes: {
    error: 0,
    success: 1
  }
};
/*
 * Dynamic properties of ContentAddMOduleController to hold instantiated Content Add's callback controls
 */
ContentAddModuleController.callbackManager = function()
{
  var self = this;
  this.bDoDefault = {
    error : true,
    success : true
  }
  this.eventList = {
    error : [],
    success : []
  };
  this.addEvent = function( sEvent,  iType )
  {
    var index;

    if( typeof sEvent === 'object' && typeof sEvent.length === 'number' )
    {
      for( index in sEvent )
      {
        self.addEvent( sEvent[ index ], iType );
      }
    }
    else if( typeof sEvent === 'string' && sEvent !== '' )
    {
      var iterationList, found = false;
      switch( iType )
      {
        case ContentAddModuleController.callbacks.callbackTypes.error:
          iterationList = this.eventList.error;
          break;

        case ContentAddModuleController.callbacks.callbackTypes.success:
          iterationList = this.eventList.success;
          break;
      }
      if( typeof iterationList !== 'undefined' )
      {
        for( index in iterationList )
        {
          if( iterationList[ index ] == sEvent )
          {
            found = true;
            break;
          }
        }
        if( found === false )
        {
          iterationList.push( sEvent );
        }
      }
    }
  };
  this.removeEvent = function( sEvent,  iType )
  {
    var index;

    if( typeof sEvent === 'object' && typeof sEvent.length === 'number' )
    {
      for( index in sEvent )
      {
        self.removeEvent( sEvent[ index ], iType );
      }
    }
    else if( typeof sEvent === 'string' && sEvent !== '' )
    {
      var iterationList;
      switch( iType )
      {
        case ContentAddModuleController.callbacks.callbackTypes.error:
          iterationList = this.eventList.error;
          break;

        case ContentAddModuleController.callbacks.callbackTypes.success:
          iterationList = this.eventList.success;
          break;
      }
      if( typeof iterationList !== 'undefined' )
      {
        for( index in iterationList )
        {
          if( iterationList[ index ] === sEvent )
          {
            iterationList.splice( index, 1 );
          }
        }
      }
    }
  };
  this.run = function( oData, iType, oWindowContext )
  {
    var iterationList, index;

    if( oWindowContext == null || typeof oWindowContext !== 'object' || typeof oWindowContext.document !== 'object' )
    {
      oWindowContext = window;
    }

    switch( iType )
    {
      case ContentAddModuleController.callbacks.callbackTypes.error:
        if( this.bDoDefault.error )
        {
          this.addEvent( ContentAddModuleController.callbacks.defaultEvents.error, iType );
        }
        iterationList = this.eventList.error;
        break;

      case ContentAddModuleController.callbacks.callbackTypes.success:
        if( this.bDoDefault.success )
        {
          this.addEvent( ContentAddModuleController.callbacks.defaultEvents.success, iType );
        }
        iterationList = this.eventList.success;
        break;
    }
    for( index in iterationList )
    {
      if( typeof iterationList[ index ] === 'string' )
      {
        oWindowContext.jQuery( oWindowContext.document ).trigger( iterationList[ index ], oData );
      }
    }
  };
};
