/* ------------------------------------------------------------------------ *
 * SAS Institute, Inc.                                                      *
 *                                                                          *
 * Copyright (c) 2002 SAS Institute, Inc.  All rights reserved.             *
 *                                                                          *
 * Contains utility classes and functions that provide additional           *
 * functionality needed by Citation dialogs. This functionality includes    *
 * support for mapping a dialog to a particular document in a parent window *
 * so that the dialog remains valid in the event the document is reloaded.  *
 * This functionality also includes support for displaying modal dialogs.   *
 *                                                                          *
 * Dependencies: citation_events.js                                         *
 *                                                                          *
 * @author Chaunston Avery (chaver)                                         *
 * ------------------------------------------------------------------------ */
function cwDialogManager() {}

cwDialogManager.modalDialog = null;

//Prefix appended to all dialogs opened by this dialog manager. The 
//default value is a string that allows easy identification of WRS 
//dialogs
cwDialogManager.dlgPrefix = 'SAS_WebReportStudio_Dialog';

//Suffix appended to all dialogs opened by this dialog manager. The 
//default value is a random integer between 0 and 100. Suggested usage 
//is to assign the sessionId or time at which the dialog is opened as 
//the value. Doing so will ensure that dialog names across user sessions are unique.
cwDialogManager.dlgSuffix = Math.floor(Math.random() * 100);

//Used to manage refs to all dlgs openend or closed from a the 
//current window. When the current window closes all open windows
//in this array should be closed as well.
cwDialogManager.dialogs = new Array();

// >>>>>>>>>>>>>>>>>>>>>>>>>>>>
// convenience keys used to retrieve a set of common windowFeatures
// >>>>>>>>>>>>>>>>>>>>>>>>>>

cwDialogManager.STD_DLG_FEATURES = "cwStandard"; //feature set for dialogs without explicitly defined keys
cwDialogManager.HELP_DLG="cwHelp";
cwDialogManager.OPEN_REPORT = "cwOpenReport";
cwDialogManager.PREFERENCES = "cwPreferences";
cwDialogManager.SEARCH_DATA_ITEMS = "cwSearchDataItems";
cwDialogManager.DATA_ITEM_PROPERTIES = "cwDataItemProperties";
cwDialogManager.DATA_SOURCE_PROPERTIES = "cwDataSourceProperties";
cwDialogManager.DEFINE_FORMAT = "cwDefineFormat";
cwDialogManager.CREATE_FILTER_TYPE_MEASURE = "cwCreateFilter_Measure";
cwDialogManager.CREATE_FILTER_TYPE_OTHER = "cwCreateFilter_Other";
cwDialogManager.SAVE_OPTIONS = "cwSaveOptions";
cwDialogManager.PREVIEW_WIZARD_DATA = "cwPreviewWizardData";
cwDialogManager.WIZARD_FILTER_SUMMARY = "cwFilterSummary";
cwDialogManager.MOVE_COPY_FILE_DIALOG = "cwMoveCopyFile";
cwDialogManager.RENAME_FILE_DIALOG = "cwRenameFile";
cwDialogManager.CREATE_FOLDER_DIALOG = "cwCreateFolderDialog";
cwDialogManager.RANK_FILTER = "cwRankFilter";
cwDialogManager.CALCULATE_NEW_ITEM = "cwCalculateItem";
cwDialogManager.EXPORT_TO_EXCEL = "cwExportToExcel";
cwDialogManager.PRINT_OPTIONS = "cwPrintOptions";
cwDialogManager.FILTER_INFORMATION = "cwFilterInfo";
cwDialogManager.DRILL_TO_DETAIL = "cwDrillToDetail";
cwDialogManager.SORT = "cwSort";
cwDialogManager.EXCEPTION_HIGHLIGHTING = "cwExceptionHighlighting";
cwDialogManager.EXCEPTION_HIGHLIGHTING_CHART = "cwExceptionHighlightingChart";
cwDialogManager.TOTALS                   = "cwTotals";
cwDialogManager.ESRI_IDENTIFY = "cwESRIIdentify";
cwDialogManager.ARCHIVED_REPORTS = "cwArchivedReports";

cwDialogManager.BUILDER_ADVANCED_QUERY   = "cwBuilderAdvancedQuery";
cwDialogManager.BUILDER_FILTER_COMBINATION   = "cwFilterCombination";
cwDialogManager.BUILDER_AGGREGATION_DETAIL   = "cwAggregationDetail";
cwDialogManager.BUILDER_EDIT_TEXT        = "cwBuilderEditText";
cwDialogManager.BUILDER_EXPORT_QUERY     = "cwBuilderExportQuery";
cwDialogManager.BUILDER_FILTER_SUMMARY   = "cwBuilderFilterSummary";
cwDialogManager.BUILDER_GRAPH_PROPERTIES = "cwBuilderGraphProperties";
cwDialogManager.BUILDER_MAP_PROPERTIES = "cwBuilderMapProperties";
cwDialogManager.BUILDER_GROUP_BREAKS     = "cwBuilderGroupBreaks";
cwDialogManager.BUILDER_HEADER_FOOTER    = "cwBuilderHeaderFooter";
cwDialogManager.BUILDER_IMPORT_QUERY     = "cwBuilderImportQuery";
cwDialogManager.BUILDER_NEW_SECTION      = "cwBuilderNewSection";
cwDialogManager.BUILDER_REORDER_SECTIONS = "cwBuilderReorderSections";
cwDialogManager.BUILDER_GALLERY_LAYOUT   = "cwBuilderGalleryLayout";
cwDialogManager.BUILDER_RENAME_SECTION      = "cwBuilderRenameSection";
cwDialogManager.BUILDER_SELECT_DATA      = "cwBuilderSelectData";
cwDialogManager.BUILDER_TABLE_PROPERTIES = "cwBuilderTableProperties";
cwDialogManager.BUILDER_EDIT_IMAGE       = "cwBuilderEditImage";
cwDialogManager.BUILDER_RENAME_DATA      = "cwBuilderRenameData";
cwDialogManager.BUILDER_PERCENT_DATA     = "cwBuilderPercentData";
cwDialogManager.BUILDER_TABLE_DATA       = "cwBuilderTableData";
cwDialogManager.BUILDER_GRAPH_DATA       = "cwBuilderGraphData";
cwDialogManager.BUILDER_MAP_DATA         = "cwBuilderMapData";

cwDialogManager.INSERT_STORED_PROCESS    = "cwInsertStoredProcess";
cwDialogManager.BUILDER_TABLE_LINK		 = "cwBuilderTableLinking";
cwDialogManager.BUILDER_GRAPH_LINK		 = "cwBuilderGraphLinking";
cwDialogManager.BUILDER_TEXT_LINK		 = "cwBuilderTextLinking";
cwDialogManager.BUILDER_BY_GROUP_LINK    = "cwBuilderByGroupLinking";
cwDialogManager.BUILDER_IMAGE_LINK		 = "cwBuilderImageLinking";
cwDialogManager.BUILDER_MAP_LINK		 = "cwBuilderMapLinking";
cwDialogManager.BUILDER_DEFINE_TABLE_PROMPT	 = "cwBuilderTableLinkPrompts";
cwDialogManager.BUILDER_DEFINE_GRAPH_PROMPT	 = "cwBuilderGraphLinkPrompts";
cwDialogManager.BUILDER_DEFINE_GROUP_PROMPT	 = "cwBuilderGroupLinkPrompts";
cwDialogManager.BUILDER_DEFINE_TEXT_PROMPT	 = "cwBuilderTextLinkPrompts";
cwDialogManager.BUILDER_DEFINE_IMAGE_PROMPT	 = "cwBuilderImageLinkPrompts";
cwDialogManager.BUILDER_DEFINE_MAP_PROMPT	 = "cwBuilderMapLinkPrompts";
cwDialogManager.REPORT_PROPERTIES        = "cwReportProperties";
cwDialogManager.PAGE_SETUP               = "cwPageSetup";
cwDialogManager.SCHEDULE_REPORT          = "cwScheduleReport";
cwDialogManager.RECIPIENT_RULES		     = "cwRecipientRules";
cwDialogManager.RECIPIENT_LIST_CREATE    = "cwRecipientListCreate";
cwDialogManager.SCHEDULE_TEST_SUMMARY    = 'cwScheduleTestSummary';
cwDialogManager.SCHEDULING_MANAGER 	     = "cwSchedulingManager";

//maps featureTypes to a set (String) of windowFeatures
cwDialogManager.featuresMap = new Array();

cwDialogManager.featuresMap[cwDialogManager.STD_DLG_FEATURES] = "width=475px,height=425px,left=20px,top=20px,resizable=yes,scrollbars=yes";
cwDialogManager.featuresMap[cwDialogManager.HELP_DLG] = "width=600px,height=400px,left=20px,top=20px,resizable=yes,scrollbars=yes,menubar=yes,status=yes,toolbar=yes";
cwDialogManager.featuresMap[cwDialogManager.OPEN_REPORT] = "width=650px,height=525px,resizable=yes,scrollbars=no";
cwDialogManager.featuresMap[cwDialogManager.PREFERENCES] = "width=600px,height=570px,resizable=yes,scrollbars=yes";
cwDialogManager.featuresMap[cwDialogManager.SEARCH_DATA_ITEMS] = "width=580px,height=145px,status=yes,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.DATA_ITEM_PROPERTIES] = "width=370px,height=255px,resizable=yes,scrollbars=yes";
cwDialogManager.featuresMap[cwDialogManager.DATA_SOURCE_PROPERTIES] = "width=500px,height=500px,resizable=yes,scrollbars=no";
cwDialogManager.featuresMap[cwDialogManager.DEFINE_FORMAT] = "width=375px,height=455px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.CREATE_FILTER_TYPE_MEASURE] = "width=350px,height=255px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.CREATE_FILTER_TYPE_OTHER] = "width=530px,height=600px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.SAVE_OPTIONS] = "width=550px,height=530px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.PREVIEW_WIZARD_DATA] = "width=725px,height=525px,resizable=yes,scrollbars=yes";
cwDialogManager.featuresMap[cwDialogManager.WIZARD_FILTER_SUMMARY] = "width=385px,height=210px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.MOVE_COPY_FILE_DIALOG] = "width=500px,height=310px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.RENAME_FILE_DIALOG] = "width=500px,height=135px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.CREATE_FOLDER_DIALOG] = "width=550px,height=135px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.RANK_FILTER] = "width=675px,height=590px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.CALCULATE_NEW_ITEM] = "width=580px,height=425px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.EXPORT_TO_EXCEL] = "width=435px,height=200px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.PRINT_OPTIONS] = "width=600px,height=350px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.FILTER_INFORMATION] = "width=600px,height=500px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.DRILL_TO_DETAIL] = "width=725px,height=525px,resizable=yes,scrollbars=yes";
cwDialogManager.featuresMap[cwDialogManager.SORT] = "width=440px,height=470px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.TOTALS] = "width=400px,height=275px,resizable=no,scrollbars=no";
cwDialogManager.featuresMap[cwDialogManager.ESRI_IDENTIFY] = "width=340px,height=430px,resizable=yes,scrollbars=no";
cwDialogManager.featuresMap[cwDialogManager.ARCHIVED_REPORTS] = "width=500px,height=500px,resizable=no,scrollbars=yes";

cwDialogManager.featuresMap[cwDialogManager.BUILDER_ADVANCED_QUERY] = "width=525px,height=660px,resizable=yes,scrollbars=yes";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_FILTER_COMBINATION] = "width=450px,height=300px,resizable=yes,scrollbars=yes";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_AGGREGATION_DETAIL] = "width=500px,height=450px,resizable=yes,scrollbars=yes";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_EDIT_TEXT] = "width=730px,height=350px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_EXPORT_QUERY] = "width=440px,height=300px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_FILTER_SUMMARY] = "width=385px,height=210px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_GRAPH_PROPERTIES] = "width=660px,height=620px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_MAP_PROPERTIES] = "width=630px,height=600px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_GROUP_BREAKS] = "width=730px,height=550px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_HEADER_FOOTER] = "width=720px,height=440px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_IMPORT_QUERY] = "width=440px,height=300px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_GALLERY_LAYOUT] = "width=580px,height=570px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_NEW_SECTION] = "width=585px,height=325px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_REORDER_SECTIONS] = "width=370px,height=350px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_RENAME_SECTION] = "width=525px,height=120px,resizable=no";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_SELECT_DATA] = "width=640px,height=510px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_TABLE_PROPERTIES] = "width=630px,height=620px,resizable=yes,scrollbars=no";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_TABLE_DATA] = "width=370px,height=485px,resizable=yes,scrollbars=no";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_GRAPH_DATA] = "width=370px,height=485px,resizable=yes,scrollbars=no";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_MAP_DATA]   = "width=390px,height=300px,resizable=yes,scrollbars=no";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_EDIT_IMAGE] = "width=700px,height=530px,resizable=yes,scrollbars=yes";
cwDialogManager.featuresMap[cwDialogManager.EXCEPTION_HIGHLIGHTING] = "width=600px,height=410px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.EXCEPTION_HIGHLIGHTING_CHART] = "width=450px,height=335px,resizable=yes";

cwDialogManager.featuresMap[cwDialogManager.BUILDER_RENAME_DATA] = "width=500px,height=150px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_PERCENT_DATA] = "width=500px,height=390px,resizable=yes,scrollbars=no";
cwDialogManager.featuresMap[cwDialogManager.INSERT_STORED_PROCESS] = "width=800px,height=520px,resizable=yes,scrollbars=yes";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_IMAGE_LINK] = "width=550px,height=500px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_TABLE_LINK] = "width=550px,height=485px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_GRAPH_LINK] = "width=550px,height=485px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_TEXT_LINK] = "width=550px,height=485px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_BY_GROUP_LINK] = "width=550px,height=560px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_MAP_LINK] = "width=550px,height=485px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.BUILDER_DEFINE_PROMPT] = "width=415px,height=325px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.REPORT_PROPERTIES] = "width=560px,height=470px,resizable=yes,scrollbars=no";
cwDialogManager.featuresMap[cwDialogManager.PAGE_SETUP] = "width=570px,height=375px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.SCHEDULE_REPORT] = "width=675px,height=575px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.RECIPIENT_RULES] = "width=675px,height=575px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.RECIPIENT_LIST_CREATE] = "width=500px,height=300px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.SCHEDULE_TEST_SUMMARY] = "width=675px,height=575px,resizable=yes";
cwDialogManager.featuresMap[cwDialogManager.SCHEDULING_MANAGER] = "width=600px,height=520px,resizable=yes,scrollbars=no";


// -----------------------------------------------------------------------------
// Opens and configures dialog with the specified features
//
// @param dlgUrl - url of the document to be displayed in the dlg
// @param dlgName - name of the window containing the dlg
// @param dlgFeatures - String of window features for the dialog (e.g.
// "width=300px,height=400px" ). This parameter may also be a key to a set of
// features stored in cwDialogManager.featuresMap
// @param bReplaceUrl - boolean that specifies whether the entry in the window's
// history list should be replaced.
// @param bModal - boolean indicating whether the dialog should be modal
// @param bReplaceIfOpen - boolean that specifies whether the dialog should be
// opened with a new document if it is already open.
// @param onDlgClosingFunc - function to call immediately before dialog is closed
// as a result of a call to closeDialog, closeCwDialog and closeDialogWindow. NULL
// is allowed.
// @param onDlgClosedFunc - function to call immediately after dialog is closed
// as a result of a call to closeDialog, closeCwDialog and closeDialogWindow NULL
// is allowed.
//
// @return cwDialog whose window object refers to the open dialog browser window
// -----------------------------------------------------------------------------
cwDialogManager.openDialog = function(
    dlgUrl,
    dlgName,
    dlgFeatures,
    bReplaceUrl,
    bModal,
    bReplaceIfOpen,
    onDlgClosingFunc,
    onDlgClosedFunc
   )
{
    var existDlg = cwDialogManager.dialogs[dlgName];
    var isDlgOpen = (existDlg != null && !existDlg.dlgWindow.closed);
    if( !bReplaceIfOpen  && isDlgOpen )
    {
        existDlg.dlgWindow.focus();
        return existDlg;
    }

    var features = cwDialogManager.featuresMap[dlgFeatures];
    if( features == null )
    {
        features = dlgFeatures;
    }

    // get width and height from features for that window
    var widthRe = /width=\d+/g;
    var widthResult = features.match(widthRe);
    var width = 0;
    if (widthResult) {
    	width = parseInt(widthResult[0].substring(6));
    }
    var heightRe = /height=\d+/g;
    var heightResult = features.match(heightRe);
    var height = 0;
    if (heightResult) {
    	height = parseInt(heightResult[0].substring(7));
    }

    // calculate left and top so that the dialog is centered
    var left = parseInt((screen.availWidth/2) - (width/2));
    var top = parseInt((screen.availHeight/2) - (height/2));
    var extraFeatures = ",left=" + left + "px,top=" + top + "px";

    // append top and left to window features
    features = features + extraFeatures;

    var browserWindowName = null;
    if( isDlgOpen )
    { //reuse existing dlg window name
        browserWindowName = existDlg.dlgWindow.name;
    }
    else
    {   //create unique window name so that window names across
        //user sessions don't collide. NOTE: The name supplied to the openDialog()
        //method is still the name that is used to obtain a reference to the dialog
        //window from cwDialogManager

        var browserWindowName = cwDialogManager.dlgPrefix + dlgName + cwDialogManager.dlgSuffix;
    }

    showDebugMsgs("openDialog", "open dialog URL="+dlgUrl+", name="+browserWindowName+", features="+features+", replace="+bReplaceUrl);
    var newDlgWin = window.open( dlgUrl, browserWindowName, features, bReplaceUrl );
    //tag window so that we can easily detect that we opened it
    try {
    	newDlgWin._cwManagerOpenedBy = cwDialogManager;    
        // showDebugMsgs("openDialog", "tagged " + newDlgWin.name + " opened by " + newDlgWin._cwManagerOpenedBy + " opener: " + newDlgWin.opener);
    } catch (e) {
        // debug;
    }

    try {
        newDlgWin.cwIsModal = ( bModal != null ? bModal : false );
        if( bModal != null && bModal )
        {
            cwDialogManager.configureModalDialog( newDlgWin, bModal );
        }
    } catch (e) {
    }

    var newDlg = new cwDialog(newDlgWin);
    cwDialogManager.dialogs[browserWindowName] = newDlg; // as of 12-02-02 store using actual window name as key

    if( onDlgClosingFunc != null ) {
        registerEventHandler ( newDlg, "WINDOW_CLOSING", onDlgClosingFunc, false );
    }

    if( onDlgClosedFunc != null ) {
        registerEventHandler ( newDlg, "WINDOW_CLOSED", onDlgClosedFunc, false );
    }

    try {
        newDlgWin.focus();
    } catch (e) {
    }

/* ----------------------
    if( newDlg.cwIsModal )
    {
      //busy-wait while modal dialog open
      while(  !newDlg.closed )
      {
        // ...
      }
    }
------------------------ */

    return newDlg;
}

// -----------------------------------------------------------------------------
// Closes a dialog of the particular name. The dialog must have been opened
// using cwDialogManager.openDialog().
//
// @param dlgName - the name of dialog to close
// -----------------------------------------------------------------------------
cwDialogManager.closeDialog = function( dlgName )
{
    var dlgToClose = cwDialogManager.dialogs[dlgName];
    return cwDialogManager.closeDialogWindow(dlgToClose.dlgWindow);
}

// -----------------------------------------------------------------------------
// Closes a dialog of the particular name. The dialog must have been opened
// using cwDialogManager.openDialog().
//
// @param dlgName - the name of dialog to close
// -----------------------------------------------------------------------------
cwDialogManager.closeCwDialog = function( cwDialog )
{
    return cwDialogManager.closeDialogWindow(cwDialog.dlgWindow);
}

// -----------------------------------------------------------------------------
// Closes a dialog window. The method can be used to close windows that were not
// opened using cwDialogManager.openDialog(), but it's primary intent is for
// closing dialogs that were. For example, it performs all needed cleanup for
// modal dialogs opened using cwDialogManager.openDialog(). The method also
// is useful because it dispatches "WINDOW_CLOSING" and "WINDOW_CLOSED" events
// to listeners registered on the dlg using the registerEventHandler() method
// in citation_events.js.
//
// @param dlgToClose - the dialog window object
// -----------------------------------------------------------------------------
cwDialogManager.closeDialogWindow = function( winToClose )
{
    // as of 12-02-02 store using actual window name as key
    var dlgToClose = cwDialogManager.dialogs[winToClose.name]; //may be null
    if( winToClose != null && !winToClose.closed )
    {
        if( winToClose.cwIsModal != null && winToClose.cwIsModal )
        {
            /* unreg all modality settings */
            cwDialogManager.configureModalDialog( winToClose, false );
        }

        if( dlgToClose != null )
        {
          //dispatch WINDOW_CLOSING event
          var closingEvent = eventNotify.eventFactory.createEvent(
                                     dlgToClose,
                                     "WINDOW_CLOSING",
                                     false /*no bubbling*/);
          eventNotify_lw( dlgToClose, closingEvent, true /*a custom event*/ );
        }

        winToClose.close();

        if( dlgToClose != null )
        {
          //dispatch WINDOW_CLOSED event
          var closedEvent = eventNotify.eventFactory.createEvent(
                                     dlgToClose,
                                     "WINDOW_CLOSED",
                                     false /*no bubbling*/ );
          eventNotify_lw( dlgToClose, closedEvent, true /*a custom event*/ );
          //cwDialogManager.dialogs[dlgName] = null;
        }
    }

    return dlgToClose;
}

// -----------------------------------------------------------------------------
// unload handler function responsible for closing all child dialogs of the
// current window
// -----------------------------------------------------------------------------
cwDialogManager.dependencyMgr = function( event )
{
    var evt = (event != null ? event : window.event);
    // var evtTarget = (evt.target != null ? evt.target : evt.srcElement);
    
    if( evt.type == "unload" ) 
    {
		for( var dlgName in cwDialogManager.dialogs)
		{
            var currDlg = cwDialogManager.dialogs[dlgName];
		    cwDialogManager.closeDialog( currDlg.name );
		}
    }
}

/**
 * Enforce that all page access occurs from a logged on session.
 * To be called at the top of pages when main application window pages are
 * attempted access from outside the main application window.
 */
cwDialogManager.enforceWindowHosting = function (rootAppWindowLocation)
{
    var rootAppWindow = cwDialogManager._getRootApplicationWindow(window);
    if (rootAppWindow == window)
    {
       return;
    }
    
    // -- rootAppWindow is not the current window --
    var rootDescendants = cwDialogManager.getDescendantWindows(rootAppWindow);
    //close descendants
    for (var i=0; i<rootDescendants.length; i++)
    {
        var descendant = rootDescendants[i];
        descendant.close();
    }
    rootAppWindow.location = rootAppWindowLocation;   
    //close this window in case it was not recognized as a descendant.
    if (!window.closed)
    {
        window.close();
    }
}

cwDialogManager._getRootApplicationWindow = function (windowRef)
{
    if (windowRef.parent != null && windowRef.parent != windowRef)
    {
        // WindowRef is most likely a remote scripting iframe (but perhaps another type of
        // frame which we claim no support for). This can happen quite frequently
        // in the builder where the iframe processes an intermediary request before
        // the final request to open a dialog is submitted. In such case, the intermediary
        // request needs to be equipped to locate the root app window.
       showDebugMsgs("cwDialogManager._getRootApplicationWindow", " window name: " + windowRef.name +  " parent: " + parent.name);
       var rootCandidate = windowRef;
       while (rootCandidate.parent != rootCandidate
           && rootCandidate.parent != null
           && rootCandidate.parent.cwDialogManager != null)
       {
           rootCandidate = rootCandidate.parent;
       }
       showDebugMsgs("getRootApplicationWindow", " returning parent: " + rootCandidate.name);
       return rootCandidate;
    }

    var root = windowRef;
    if (root.opener != null)
    {
        // showDebugMsgs("_getRootApplicationWindow", "opener: " + root.opener.name);
	    while ( root.opener != null
		         && root.opener.cwDialogManager != null
		         && root.opener.cwDialogManager.isManaged(root))
	    {
	        // showDebugMsgs("_getRootApplicationWindow", " follow opener link of: " + root.name + " root opener name: " + root.opener.name);
	        root = root.opener;
	    }
    }
    // showDebugMsgs("_getRootApplicationWindow", " returning : " + root.name);
    return root;
}

cwDialogManager.getDescendantWindows = function (windowRef)
{
    var descendants = new Array();
    cwDialogManager._getDescendantWindows(windowRef, descendants);
    return descendants;
}

cwDialogManager._getDescendantWindows = function (windowRef, descendants)
{
    var dlgManager = windowRef.cwDialogManager;
    if (dlgManager == null) {
        return;
    }
    
    for( var i = 0; i<dlgManager.dialogs.length; i++ )
    {
        var currDlg = dlgManager.dialogs[i];
        descendants[descendants.length] = currDlg.dlgWindow;
        cwDialogManager._getDescendantWindows(currDlg.dlgWindow, descendants);
    }
}

//Returns true if the specified dialog is managed by
//the dialog manager. Returns false otherwise. A dialog
//is considered managed by the manager if it was opened
//by the manager. 
cwDialogManager.isManaged = function(windowRef)
{
    if (windowRef._cwManagerOpenedBy == cwDialogManager)
    {
        return true;
    }
    
    for( var dlgName in cwDialogManager.dialogs)
    {
        var dlg = cwDialogManager.dialogs[dlgName];
        if (dlg.dlgWindow == windowRef) 
        {
            showDebugMsgs("isManaged", windowRef.name + " IS in list of managed dialogs under " + window.name );
            return true;
        }
    }
    showDebugMsgs("isManaged", windowRef.name + " is not a managed dialog.");
    return false;    
}

cwDialogManager.configureModalDialog = function( dlg, setModal )
{
    dlg.cwIsModal = ( setModal != null ? setModal : true );
    if( dlg.cwIsModal ) 
    {
        var bRegisterListener = (cwDialogManager.modalDialog == null);
        cwDialogManager.modalDialog = dlg;

        if( bRegisterListener ) {
            //previous modal dialog has not been opened from the current window 
            //so focus listener needs be registered
            //alert("registering modality mgr");
            registerEventHandler( self, "focus", cwDialogManager.modalityMgr, false );
            registerEventHandler( self, "resize", cwDialogManager.modalityMgr, false );
        }
        //registerEventHandler( dlg, "unload", cwDialogManager.modalityMgr, false );
    }
    else 
    {
        unRegisterEventHandler( self, "focus", cwDialogManager.modalityMgr, false );
        unRegisterEventHandler( self, "resize", cwDialogManager.modalityMgr, false );
        cwDialogManager.modalDialog = null;
    }
}

//onfocus handler whose job it is to reassign focus to the modal dialog when
//when the user attempts to move focus to main parent window
cwDialogManager.modalityMgr = function( event )
{
    var evt = (event != null ? event : window.event);
    var evtTarget = (evt.target != null ? evt.target : evt.srcElement);

    //veto events on the current window if there is a modal 
    //dialog open when the event is triggered.
    if( evt.type == "focus"
        || evt.type == "resize" //one of action types triggered outside window's document
        ) 
    {
        //alert("rerouting focus");
        if( cwDialogManager.modalDialog != null
            && !cwDialogManager.modalDialog.closed )
        {
            cwDialogManager.modalDialog.focus();
            return false;

        }
    }
    else if( evt.type == "unload" ) 
    {
        //alert("unmapping focus listener");
        cwDialogManager.configureModalDialog( cwDialogManager.modalDialog, false /* unreg all modality settings */ )
    }

}

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// functions needed to map a dialog to a parent window
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

// variables used by the dialog manager. These variables should be set based
// on the needs of the dialog
cwDialogManager.appContext = null; // required -- used to detect when location of parent window moves outside our web context
cwDialogManager.conditionVariableName = "g_wizardStep"; //default
cwDialogManager.conditionValue = 1; //default
//Flag that indicates if parent window's document is valid for this document.
//Used by removeParentDependencies to determine if it should actually remove
//parent dependencies upon closing of the dialog.
cwDialogManager.isParentDocumentValid = true;

// -----------------------------------------------------------------------------
// This function is assigned in a dialog and entirely optional. Its job is to
// attach any custom dependencies to the parent. If set, this function will be
// called as part of the initializeParentDependencies() method.
// -----------------------------------------------------------------------------
cwDialogManager.attachCustomParentDependenciesFunction = null;

// -----------------------------------------------------------------------------
// To map the dialog to its parent initially this function should be called by
// the dialog when it is first opened.  Whenever it is necessary to remap the
// dialog to the parent window (e.g. in cases when the parent reloads its
// document but the dialog should remain open) cwDialogManager will make
// subsequent calls to this function to remap the dialog.
// -----------------------------------------------------------------------------
cwDialogManager.initializeParentDependencies = function()
{
    registerEventHandler ( self.opener, "unload", cwDialogManager.onParentUnload, false );
    //registerEventHandler( self, "unload", cwDialogManager.removeParentDependencies, false );

    if( cwDialogManager.attachCustomParentDependenciesFunction != null )
    {
        cwDialogManager.attachCustomParentDependenciesFunction();
    }

    //alert("initializing Dependencies complete");
}

cwDialogManager.onParentUnload = function()
{
    // a 2 second delay, give parent window time to change its href
    setTimeout("cwDialogManager.validateParentDialogDependency()", 2000)
}

// -----------------------------------------------------------------------------
// In the event the parent window unloads it document this function determines
// if the dialog should remain open. If so, it remaps the dialog to the parent
// window.  Otherwise, it closes the dialog.
// -----------------------------------------------------------------------------
cwDialogManager.validateParentDialogDependency = function()
{
    try {
        if( !cwDialogManager.leaveDialogOpenOk() )
        {
            //set flag indicating parent dependencies should be removed upon unloading of dialog's document
            cwDialogManager.isParentDocumentValid = false;
            self.close();
        }
        else {
            cwDialogManager.remapDialog();
        }
    }
    catch(e) {
        //set flag indicating parent dependencies should be removed upon unloading of dialog's document
        cwDialogManager.isParentDocumentValid = false;

        //Catch the error that might be thrown. (e.g. when an attempt is made to read location from different
        //web server.   Leaving the server serving this app => close the dialog
        self.close();
    }

}

// -----------------------------------------------------------------------------
// Remaps the dialog to the parent window once the parent window's document
// has been fully loaded.
// -----------------------------------------------------------------------------
cwDialogManager.remapDialog = function()
{
    if( self.opener.g_pageLoaded != null && !self.opener.g_pageLoaded ) {
        //alert("parent still not loaded");
        setTimeout( "cwDialogManager.remapDialog()", 1000);
    }
    else { //remap the dialog
        //alert("remapping dialog");
        cwDialogManager.initializeParentDependencies();
        return;
    }

}

// -----------------------------------------------------------------------------
// If the parent window reloads its document and the conditionVariable
// and its value remain the same for the parent, then this function returns
// true indicating that the dialog should remain open if already so. Otherwise,
// this function returns false;
// -----------------------------------------------------------------------------
cwDialogManager.leaveDialogOpenOk = function()
{
    //alert("testing if ok to leave up dialog");
    try {
        var parentSite = self.opener.location.href;

        var strToEval = "self.opener." + cwDialogManager.conditionVariableName + ";"
        var conditionVariable = eval(strToEval);
        //alert("conditionVariable Value = " + conditionVariable + "\ndialogMgr value = " + cwDialogManager.conditionValue );
        if( conditionVariable  == null
            || conditionVariable != cwDialogManager.conditionValue
            || parentSite.indexOf(cwDialogManager.appContext) == -1 )
        {
            //same server different webapp => close dialog
            return false;
        }
    }
    catch(e) {
        //leaving the server serving this app
        return false;
    }
    return true;
}

//Responsible for unmapping the dialog in the event it is closed while parent
//window still open
cwDialogManager.removeParentDependencies = function()
{
    if( !cwDialogManager.isParentDocumentValid )
    {
        unRegisterEventHandler( self.opener, "unload", cwDialogManager.removeParentDependencies, false );
        //alert("parent dependencies removed");
    }
}

// -----------------------------------------------------------------------------
// cwDialog class - a dialog has an associated window and a set of event
// listeners. The purpose of associating event listeners with a cwDialog object
// is so that listeners can remain associated with the dialog even after the
// the dialog has been closed or the window's document has been unloaded or reloaded.
//
// NOTE: Listeners registered on the dialog object are mainly for use by objects
// outside the dialog's window.
// -----------------------------------------------------------------------------
cwDialog.prototype.addEventListener = cwAddEventListener;
cwDialog.prototype.removeEventListener = cwRemoveEventListener;
cwDialog.prototype.dispatchEvent = cwDispatchEvent;

function cwDialog(dlgWin)
{
  this.dlgWindow = dlgWin;
}
