//====START_GENERATED_PROLOG======================================
//
//
//   COMPONENT_NAME: oddataxfer
//
//   CLASSES: none
//
//   ORIGINS: 82,27,94
//
//
//   (C) COPYRIGHT International Business Machines Corp. 1995,1996
//   All Rights Reserved
//   Licensed Materials - Property of IBM
//   US Government Users Restricted Rights - Use, duplication or
//   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
//
//   IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
//   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//   PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
//   CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
//   USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
//   OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
//   OR PERFORMANCE OF THIS SOFTWARE.
//
//====END_GENERATED_PROLOG========================================
//
// @(#) 1.29 nt/src/storage/WLnkDlgs.cpp, oddataxfer, od96nt, odnt9712d 3/7/97 11:21:30 [ 3/21/97 17:14:14 ]
/*
   File:       LinkDlgs.cpp            ** DO NOT REMERGE WITH APPLE CODE **

   Contains:   implementation of the Paste As and Link Info dialogs

   Written by: Craig Carper
   Recoded to Windows By: Brad Tolman

   Copyright:  c 1993-94 by Apple Computer, Inc., all rights reserved.

   Change History (most recent first):

       <12>     8/19/96    DJ      24768: Fix helps on Link Dlgs
       <11>    10/31/94    CG      #1147225: Moved ContentValueTypes to
                                   InfoUtil.cpp.
       <10>    10/27/94    CG      #1147225: Moved AddTypesToMenu to
                                   InfoUtil.cpp.
        <9>     10/7/94    CC      1160232 - Added calls to
                                   EndUsingLibraryResources().
        <8>     10/4/94    CC      1190299 - Use utility fcns in InfoUtil.h
                                   and DlogUtil.h.
        <7>     9/20/94    CC      1160232 - Added ShowLinkUpdateAlert()
                                   1153930 - Added TranslateValueTypes() and
                                   other mods to add translation choices to
                                   Paste As dialog.
        <6>     8/10/94    CC      1179943 - LinkInfo dialog functions take
                                   ODBaseLink and ODBaseLinkSource parameters.
        <5>      8/2/94    CC      #1178169 - ShowPasteAsDialog() takes
                                   ODFacet* instead of ODFrame*.
        <4>     7/31/94    CC      ShowLinkDestinationInfo - fix to display
                                   dialog correctly.
        <3>     7/27/94    CC      Allocate kindList (a SOM object) on the
                                   heap, not the stack.
        <2>      7/5/94    CC      Added typecasts of pascal strings for PPCC
                                   compiler.
        <1>     6/24/94    CC      first checked in
        <0>     6/13/94    SV      SOMverted

       ------------------- CC ---- Converted to SOM

       <14>      6/1/94    CG      Changed to use new public binding object.
       <13>     5/11/94    T       #1162405 Removed explicit ASLM dependency
                                   for using resources (missed a couple)
       <12>     5/10/94    T       #1162405 Removed explicit ASLM dependency
                                   for using resources
       <11>      5/9/94    MB      #1162181: Changes necessary to install MMM.
       <10>      4/6/94    CC      XMPTypeInfo: Changed field "creationDate"
                                   to "creationTime" and "modificationDate" to
                                   "changeTime". (1154722)
        <9>      4/4/94    CC      Convert from using XMPTypeSet to
                                   XMPTypeList (1153046).
        <8>      4/1/94    T       #1154941: Get OpenDoc source to actually
                                   compile for PowerPC
        <7>     3/28/94    CG      1153547: Renamed XMPSessn.h to XMPSessM.h.
        <6>     3/25/94    JA      Added missing #include (1147588)
        <5>     3/25/94    eeh     bug #1153053: Changes for PPC nativity.
        <4>     3/24/94    CC      ShowLinkSourceInfo() takes XMPChangeID
                                   parameter; XMPPasteAsResult specifies
                                   original kind when selected kind is a
                                   translation (1153068).
        <3>     3/17/94    CC      Added ShowLinkSourceInfo() and
                                   ShowLinkDestinationInfo(). (1151329)
        <1>     3/14/94    CC      first checked in
        <0>     3/14/94    CC      Create ShowPasteAsDialog (1144253).

   To Do:

     To dim text, build a pattern on the fly containing the color midway
   between the foreground and background color.

     Stop annoying flash of static text items initially dimmed.

     Radio button rectangles should include static text item; requires
   redraw of static text when button is re-enabled.

     Dialog does not contain color pictures

     Add translation choices

     OK button should be disabled if currently selected kind is disabled.

     $$$$$ Use script of user string for kind?

     Selection of best merge kind doesn't consider the destination's category

   Link Info

     Change "Modified:" to "Updated:".
     Dim Update Now button if automatic was checked upon entry (and keep
       dim even if changed to manual?).
     Get Updates doesn't apply if the source is in the same document.
       At least dim Manually.
     "Updated:" date should be the time the source changed (the destination
       part needs access to this value).
     Use Finder display for size (showing K for large sizes).
     "Send updates:" should be disabled if the link doesn't publish.
*/

#ifndef _STDTYPIO_
#include <StdTypIO.h>
#endif 

#ifndef _LINKDLGS_
#include "LinkDlgs.h"
#endif

#ifndef SOM_ODNameSpace_xh
#include <NamSpac.xh>
#endif

#ifndef _BNDNSUTL__
#include <BndNSUtl.h>
#endif

#ifndef SOM_ODSession_xh
#include <ODSessn.xh>
#endif

#ifndef _EXCEPT_
#include "Except.h"
#endif

#ifndef _LINKDEFS_
#include "LinkDefs.h"
#endif

#ifndef _DOCUTILS_
#include <DocUtils.h>
#endif

#ifndef SOM_Module_OpenDoc_StdProps_defined
#include <StdProps.xh>
#endif

#ifndef SOM_Module_OpenDoc_StdTypes_defined
#include <StdTypes.xh>
#endif

#ifndef SOM_ODTypeList_xh
#include <TypeList.xh>
#endif

#ifndef SOM_ODTypeListIterator_xh
#include <TypLsItr.xh>
#endif

#ifndef SOM_ODStorageUnit_xh
#include "StorageU.xh"
#endif

#ifndef SOM_ODPart_xh
#include <Part.xh>
#endif

#ifndef SOM_ODPartWrapper_xh
#include <PartWrap.xh>
#endif

#ifndef SOM_ODFrame_xh
#include <Frame.xh>
#endif

#ifndef SOM_ODFacet_xh
#include <Facet.xh>
#endif

#ifndef SOM_ODBaseLink_xh
#include <LinkB.xh>
#endif

#ifndef SOM_ODBaseLinkSource_xh
#include <LinkSrcB.xh>
#endif

#ifndef SOM_ODBinding_xh
#include <ODBindng.xh>
#endif

#ifndef SOM_RegistryManager_xh
#include <RManager.xh>
#endif 

#ifndef _ODPRTREIG_
#include <ODPrtRei.xh>
#endif

#ifndef SOM_ODPartHandlerRegistry_xh
#include <ODPrtReg.xh>
#endif 

#ifndef SOM_ODTranslation_xh
#include "Translt.xh"
#endif

#ifndef _ODUTILS_
#include "ODUtils.h"
#endif

#ifndef _PASCLSTR_
#include "PasclStr.h"
#endif

#ifndef _EDITRSET_
#include "EditrSet.h"
#endif

#ifndef _ISOSTR_
#include "ISOStr.h"
#endif

#ifndef _ODMEMORY_
#include "ODMemory.h"
#endif

#ifdef OD_PAGETUNE_H
#include <ODPagtun.h>
#endif

#ifndef _ODUTILW_
#include "ODUtilW.h"
#endif

#ifndef _OLEDATA_H_
#include "OleData.h"
#endif

#ifndef _OLEXFER_H_
#include "OleXfer.h"
#endif

#ifndef SOM_ODHelp_xh
#include <ODHelp.xh>
#endif

#include <hlppanls.h>

#include <resource.h>

#include <odres.h>

#include <rmutil.h>

#include <qprintf.h>
#include <wchar.h>
#include <DraftWn.h>
#include <langinfo.h>
//#define RRK_DEBUG 1
//==============================================================================
// Constants
//==============================================================================

const short kControlInactive = 255;
const short kControlActive = 0;

//==============================================================================
// Scalar types
//==============================================================================
typedef char ODHandleState;


//==============================================================================
// Static globals
//==============================================================================
static ODPasteAsResult*    gPAResult;
static ODLinkInfoResult*   gLIResult;
static ODTypeList*         gKindList;
static ODSShort                gKindItem;
static ODSShort            EditorItem;
static ODBoolean           gCanEmbed;
static ODSShort                 gAlertResult;
static ODFacet*            gFacet;
static ODSession*          gSession;

static ODBaseLink*		   gLink;              // passed in to ShowLinkDestinationInfo function.
static ODUpdateID	   gUpdateID;           // passed in to ShowLinkSourceInfo function.
static ODBoolean	   gChangesAllowed;    // passed in to both Link info functions.
// rrk 20 aug 96
static ODPasteAsMergeSetting gMergeSetting;
static ODStorageUnit*	     gpContentSU;
static ODTypeToken	     gViewType;
// rrk 19 apr 96
HINSTANCE                       ghDllInstance;
//==============================================================================
// Function declarations
//==============================================================================

BOOL CALLBACK PasteSpecialDlgProc (HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK LinkSourceInfoDlgProc (HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK LinkDestInfoDlgProc (HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK LinkUpdateAlertDlgProc (HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam);

ODStatic ODType BestContentKind(ODStorageUnit* contentSU);

ODStatic ODBoolean DraftIsReadOnly(Environment* ev, ODStorageUnit* su);

ODStatic ISOString GetDisplayKind(ODType type, ODSession* session);
//------------------------------------------------------------------------------
// GetSelectedType
//------------------------------------------------------------------------------

ODStatic ODType GetSelectedType(ODTypeList* typeList, ODSShort typeIndex)
{
   Environment*        ev = somGetGlobalEnvironment();
   ODType              type;
   ODTypeListIterator* iter = typeList->CreateTypeListIterator(ev);

   for ( type = iter->First(ev);
         (--typeIndex >= 0) && iter->IsNotComplete(ev);
         type = iter->Next(ev) )
   {
   }

   delete iter;

   if ( type != (ODType) kODNULL )
       type = ODISOStrFromCStr((char *) type);

   return type;
}

//------------------------------------------------------------------------------
// InitialMergeSetting
//------------------------------------------------------------------------------

ODStatic ODBoolean InitialMergeSetting(
                   ODTypeList* kinds,
                   ODEditor        editor,
                   ODNameSpaceManager* nsm)
{
   Environment*        ev = somGetGlobalEnvironment();
   ODTypeListIterator* typeIter = kinds->CreateTypeListIterator(ev);
   ODType              bestKind = typeIter->First(ev);

   delete typeIter;

   // HI spec says something about choosing merging if destination editor
   // is the same category as the content.  For now, initially choose merging
   // if the editor supports the best kind without translation.

   //#ifdef _PLATFORM_WIN32_
   //  return ( IsEditorOfKind( bestKind, editor ));
   //#else
   return (EditorSupportsKind( nsm, editor, bestKind ));
   //#endif
}


//------------------------------------------------------------------------------
// IndexOfKindInList
//------------------------------------------------------------------------------
ODSShort IndexOfKindInList(ODTypeList* kindList, ODType kind)
{
	ODSShort retVal = 0;
	
	Environment* ev = somGetGlobalEnvironment();

	if ( kindList->Count(ev) )
	{
		ODSShort i = 1;
		ODTypeListIterator* kindIter = kindList->CreateTypeListIterator(ev);
		
		TRY
		
			for (ODType type = kindIter->First(ev);
				kindIter->IsNotComplete(ev);
				type = kindIter->Next(ev), i++)
			{
				if ( ODISOStrEqual(type, kind) )
					retVal = i;
				ODDisposePtr(type);
				if ( retVal != 0 )
					break;
			}

		CATCH_ALL
			ODDeleteObject(kindIter);
			RERAISE;
		ENDTRY
		
		ODDeleteObject(kindIter);
	}
	
	return retVal;
}

//------------------------------------------------------------------------------
// BestMergeKindSetting
//------------------------------------------------------------------------------

ODStatic ODSShort BestMergeKindSetting(
					ODTypeList*			kinds,
					ODType				bestKind,
					ODEditor			editor,
					ODNameSpaceManager*	nsm)
{
	if ( bestKind && EditorSupportsKind(nsm, editor, bestKind) )
		return IndexOfKindInList(kinds, bestKind);
	
	Environment*		ev = somGetGlobalEnvironment();
	ODSShort			kindItem = 0;		// Default in case none are supported

	ODTypeListIterator*	iter = kinds->CreateTypeListIterator(ev);
	
	ODType				type;
	ODSShort			i;
	for ( type = iter->First(ev), i = 1; 
		  iter->IsNotComplete(ev); 
		  type = iter->Next(ev), ++i )
	{
		ODBoolean supports = EditorSupportsKind(nsm, editor, type);
		ODDisposePtr(type);
		if ( supports )
		{
			kindItem = i;
			break;
		}
	}

	delete iter;
	
	return kindItem;
}

//------------------------------------------------------------------------------
// BestContentKind
//------------------------------------------------------------------------------
ODStatic ODType BestContentKind(ODStorageUnit* contentSU)
{
	Environment* ev = somGetGlobalEnvironment();

	ODType bestKind = ODGetISOStrProp(ev, contentSU, kODPropPreferredKind, kODISOStr, kODNULL, kODNULL);

	if ( bestKind == kODNULL )
	{
		if (contentSU->Exists(ev, kODPropContents, (ODValueType)kODNULL, 1))
		{
			contentSU->Focus(ev, kODPropContents, kODPosUndefined, (ODValueType)kODNULL, 1, kODPosUndefined);
			bestKind = contentSU->GetType(ev);
		}
	}
	
	return bestKind;
}

//------------------------------------------------------------------------------
// TranslateValueTypes
//------------------------------------------------------------------------------
ODStatic void TranslateValueTypes(
               ODTypeList* kindList,
               ODTypeList* translateToList,
               ODTypeList* translateFromList,
               ODSession*  session)
{
   // $$$$$ Should throw exceptions instead of returning incomplete results.

   Environment* ev = somGetGlobalEnvironment();

   ODTranslation* translation = session->GetTranslation(ev);

   ODTypeListIterator* kindIter = kindList->CreateTypeListIterator(ev);

   for (ODType kind = kindIter->First(ev);
       kindIter->IsNotComplete(ev);
       kind = kindIter->Next(ev))
   {
       TRY

           somPrintf("Calling GetTranslationOf with kind %s\n", kind);
           ODTypeList* toList = translation->GetTranslationOf(ev, kind);
           somPrintf("Got toList = %p\n", toList);

           ODTypeListIterator* toIter = toList->CreateTypeListIterator(ev);

           for (ODType toKind = toIter->First(ev);
               toIter->IsNotComplete(ev);
               toKind = toIter->Next(ev))
           {
               TRY

                   if ( (kindList->Contains(ev, toKind) == kODFalse)
                       &&
                        (translateToList->Contains(ev, toKind) == kODFalse)
                      )
                   {
                       translateToList->AddLast(ev, toKind);
                       translateFromList->AddLast(ev, kind);
                   }

               CATCH_ALL
               ENDTRY
           }
           delete toIter;
           delete toList;

       CATCH_ALL
       ENDTRY
   }
   delete kindIter;
}

//------------------------------------------------------------------------------
// AddTypesToList
//------------------------------------------------------------------------------
ODStatic void AddTypesToList(ODNameSpaceManager *nsm, ODTypeList* typeList, HWND kindList, ODSession* session)
{
   Environment* ev = somGetGlobalEnvironment();
   BOOL    bFirstKind  = TRUE;
   char* myString;
   myString = catgets(ODcat_handle, LINKSPEC_SET, LINKSPEC_80, "No user kind");

   if (!typeList->Count(ev))
   {
       LPSTR strPtr = myString;
       SendMessage (kindList, CB_ADDSTRING, 0, (LPARAM)strPtr);
       EnableWindow (kindList, FALSE);
   }
   else
   {
       ODTypeListIterator* typeIter = typeList->CreateTypeListIterator(ev);

       for (ODType type = typeIter->First(ev);
           typeIter->IsNotComplete(ev);
           type = typeIter->Next(ev))
       {
           
           char    szUserKind[256];
	   memset(szUserKind,0,256);
	   
	   ISOString   theName = GetDisplayKind(type, session);
           ODSShort len = ODISOStrLength( theName );
           if (len > 255 ) len = 255;
               ODBlockMove( theName, szUserKind, len);

           SendMessage(kindList, CB_ADDSTRING, 0, (LPARAM)szUserKind);
           if (bFirstKind){
                   SendMessage(kindList, CB_SELECTSTRING, (WPARAM)-1, (LPARAM)szUserKind);
                   bFirstKind  = FALSE;
	   delete theName;
           }
       }
       delete typeIter;
   }
}


//------------------------------------------------------------------------------
// ShowPasteAsDialog
//------------------------------------------------------------------------------

ODBoolean ShowPasteAsDialog(
               ODBoolean           canPasteLink,
               ODPasteAsMergeSetting mergeSetting,
               ODBoolean           isMove,
               ODStorageUnit*      contentSU,
               ODFacet*            facet,
               ODTypeToken         viewType,
               HWND                    hwnd,             // rr 24 apr 96
               ODPasteAsResult*    result)

{
   Environment *ev = somGetGlobalEnvironment();

   // Do we allow linking?  First, check to see if an OpenDoc link is available:
   if (canPasteLink)
	canPasteLink = contentSU->Exists(ev, kODPropLinkSpec, (ODValueType) kODLinkSpec, 0);

   // If it is not an OpenDoc link, perhaps a native Ole link is available:
   if (!canPasteLink)
	canPasteLink = contentSU->Exists(ev, kODPropContents, (ODValueType) kODLinkSpec, 0);

   result->pasteLinkSetting  = (!isMove) && canPasteLink;
   result->autoUpdateSetting = kODTrue;
   result->translateKind     = (ODType) kODNULL;
   result->selectedKind      = (ODType) kODNULL;
   result->editor            = kODNoEditor;

   gPAResult = result;
   gpContentSU = contentSU;
   gMergeSetting = mergeSetting;
   gViewType     = viewType;

   // Load the resource file
   HINSTANCE resInstance = LoadLibrary("ODRES.DLL");

   if (DialogBoxParam (resInstance, MAKEINTRESOURCE(IDD_PASTEASDLG), hwnd,
       (DLGPROC)PasteSpecialDlgProc, (LPARAM)facet) < 0)
     {
       WARNMSG_DEBUG(WARN_INDEX(-1),"WLnkDlgs: ERROR on DialogBoxParam; GetLastError returns %d.\n", GetLastError());
            return kODFalse;
     }

   if (gPAResult){
#ifdef USE_VIEWAS
       // update ViewAs
       switch (gPAResult->selectedView)
       {
           case 0: // view as frame
               frame->ChangeViewType(ev, session->Tokenize(ev, kODViewAsFrame));
               break;
           case 1: // view as large icon
               frame->ChangeViewType(ev, session->Tokenize(ev, kODViewAsLargeIcon));
               break;
           case 2: // view as small icon
               frame->ChangeViewType(ev, session->Tokenize(ev, kODViewAsSmallIcon));
               break;
           case 3: // view as thumbnail
               frame->ChangeViewType(ev, session->Tokenize(ev, kODViewAsThumbnail));
               break;
           default:
               break;
       }
#endif

#ifdef RRK_DEBUG
       PRINT("*** RRK ODPasteAsResult structure.\n");
       PRINT("\t pasteLinkSetting:\t %d.\n", result->pasteLinkSetting);
       PRINT("\t autoUpdateSetting:\t %d.\n", result->autoUpdateSetting);
       PRINT("\t mergeSetting:\t %d.\n", result->mergeSetting);
       PRINT("\t selectedView:\t %d.\n", result->selectedView);
       PRINT("\t selectedKind:\t %s.\n", result->selectedKind);
       PRINT("\t translateKind:\t %s.\n", result->translateKind);
       PRINT("\t editor:\t %s.\n", result->editor);
#endif
       return kODTrue;
   }else
       return kODFalse;
}

//------------------------------------------------------------------------------
// ShowLinkSourceInfo
//------------------------------------------------------------------------------
ODBoolean ShowLinkSourceInfo(
               ODBaseLinkSource*   linkSource,
               ODUpdateID          change,
               ODBoolean           changesAllowed,
               HWND                hwnd,
               ODFacet*            facet,
               ODLinkInfoResult*   infoResult)

{
   Environment *ev = somGetGlobalEnvironment();

   gLIResult = infoResult;

   gFacet = facet;
   gSession = gFacet->GetFrame(ev)->GetStorageUnit(ev)->GetSession(ev);
   gUpdateID = change;
   gChangesAllowed = changesAllowed;

   // Load the resource file
   HINSTANCE resInstance = LoadLibrary("ODRES.DLL");

   DialogBoxParam (resInstance, MAKEINTRESOURCE(IDD_LSPAGEDLG), hwnd,
       (DLGPROC)LinkSourceInfoDlgProc, (LPARAM)linkSource);

   if (gLIResult){
       return kODTrue;
   }else
       return kODFalse;
}

//------------------------------------------------------------------------------
// ShowLinkDestinationInfoDlg
//------------------------------------------------------------------------------
ODBoolean ShowLinkDestinationInfo(
               ODBaseLink*         link,
               ODLinkInfo*         info,
               ODBoolean           ChangesAllowed,
               HWND                    hwnd,
               ODFacet*                facet,
               ODLinkInfoResult*   infoResult)

{
   Environment *ev = somGetGlobalEnvironment();

   gLIResult = infoResult;
   gLink     = link;
   gChangesAllowed = ChangesAllowed;

   gFacet = facet;
   gSession = gFacet->GetFrame(ev)->GetStorageUnit(ev)->GetSession(ev);

   // Load the resource file
   HINSTANCE resInstance = LoadLibrary("ODRES.DLL");

   DialogBoxParam (resInstance, MAKEINTRESOURCE(IDD_LDPAGEDLG), hwnd,
       (DLGPROC)LinkDestInfoDlgProc, (LPARAM)info);

   if (gLIResult){
       return kODTrue;
   }else
       return kODFalse;
}

//------------------------------------------------------------------------------
// PasteSpecialDlgProc
//------------------------------------------------------------------------------
BOOL CALLBACK PasteSpecialDlgProc (HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
   Environment *ev = somGetGlobalEnvironment();
   static ODNameSpaceManager* nsm;
   static ODEditor editorID;
   static ODBinding* binding;

   switch (Message) {
       case WM_INITDIALOG:
           {
               ODFacet  *facet    = (ODFacet*)lParam;
               ODFrame  *frame    = facet->GetFrame(ev);
               ODPart   *part     = frame->AcquirePart(ev);
               ODWindow* window   = facet->GetWindow(ev);
               ODSession* session = frame->GetStorageUnit(ev)->GetSession(ev);

               binding = session->GetBinding(ev);
               nsm = session->GetNameSpaceManager(ev);
               // 19 apr 96 rrk
               //editorID = GetCurrentEditorForPart(part);
               editorID = ((ODPartWrapper*)part)->GetEditor(ev);

               //  set up Kind List
               gKindList = new ODTypeList;
               gKindList->InitTypeList(ev,(ODTypeList*) kODNULL);
               ContentValueTypes(gpContentSU, gKindList);
               HWND hKindList = GetDlgItem(hWnd, IDD_PARTKIND);

               AddTypesToList(nsm, gKindList, hKindList, session);
               gPAResult->selectedKind = 0;

	       // Determine the indices of the best kind and the best kind that can be merged
	       ODType bestKind = kODNULL;
	       bestKind = BestContentKind(gpContentSU);

               ODSShort bestKindIndex = 1;
	       if ( bestKind )
			bestKindIndex = IndexOfKindInList(gKindList, bestKind);
	       if ( bestKindIndex == 0)   // In case preferred kind property is bogus
		        bestKindIndex = 1;

               ODSShort bestMergeKind = BestMergeKindSetting(gKindList, bestKind, editorID, nsm);

//               ODBoolean canMerge = (bestMergeKind != 0);

               // Set the Source Text
               // removed since not on MAC DR4
               // SetDlgItemText (hWnd, IDC_SOURCETXT, editorID);

               //  Set the Editor Text
               // rrk 19 apr 96
               char    szUserEditor[256];
	       memset(szUserEditor,0,256);
               ISOString  theName;
	       ODPartHandlerRegistryInt* odRegistry;
	       odRegistry = session -> GetRegistry(ev);
	       char* myString;

	       theName =  odRegistry->GetHandlerDisplayNameFromHandler(ev, editorID);
	       if ( (strcmp(theName, "GetHandlerDisplayName: partHandlerName==NULL") != 0)
                  && (strcmp(theName, "GetHandlerDisplayName: partHandlerName NOT found") != 0) )
	                {
                   ODSShort len = ODISOStrLength( theName );
                   if (len > 255 ) len = 255;
                       ODBlockMove( theName, szUserEditor, len);

		   LPSTR strPtr = (LPSTR) ODNewPtrClear(len);
                   ODBlockMove( theName, strPtr, len);
                   SetDlgItemText (hWnd, IDD_PARTEDITOR, szUserEditor);
                   gPAResult->editor = strPtr;
               }
               else {
	           myString = catgets(ODcat_handle, LINKSPEC_SET, LINKSPEC_90, "No user editor");
                   SetDlgItemText (hWnd, IDD_PARTEDITOR, myString);
	       }

               // set the Embed List

	       myString = catgets(ODcat_handle, LINKSPEC_SET, LINKSPEC_40, "Frame");
               SendDlgItemMessage (hWnd, IDD_EMBEDAS, CB_INSERTSTRING, 0,
                   (LPARAM)myString);
	       myString = catgets(ODcat_handle, LINKSPEC_SET, LINKSPEC_50, "Large Icon");
               SendDlgItemMessage (hWnd, IDD_EMBEDAS, CB_INSERTSTRING, 1,
                   (LPARAM)myString);
	       myString = catgets(ODcat_handle, LINKSPEC_SET, LINKSPEC_60, "Small Icon");
               SendDlgItemMessage (hWnd, IDD_EMBEDAS, CB_INSERTSTRING, 2,
                   (LPARAM)myString);
	       myString = catgets(ODcat_handle, LINKSPEC_SET, LINKSPEC_70, "Thumb Nail");
               SendDlgItemMessage (hWnd, IDD_EMBEDAS, CB_INSERTSTRING, 3,
                   (LPARAM)myString);

 //              ODTypeToken view = frame->GetViewType(ev);
               ODUShort viewval = 0;

               if (gViewType == session->Tokenize(ev, kODViewAsFrame))
                   viewval = 0;
               else if (gViewType == session->Tokenize(ev, kODViewAsLargeIcon))
                   viewval = 1;
               else if (gViewType == session->Tokenize(ev, kODViewAsSmallIcon))
                   viewval = 2;
               else if (gViewType == session->Tokenize(ev, kODViewAsThumbnail))
                   viewval = 3;

               SendDlgItemMessage (hWnd, IDD_PARTKIND, CB_SETCURSEL, 0,       0L);
               SendDlgItemMessage (hWnd, IDD_EMBEDAS,  CB_SETCURSEL, viewval, 0L);
               CheckDlgButton(hWnd, IDD_PASTEAUTOBTN, kODTrue);
               gPAResult->autoUpdateSetting = kODTrue;

               if (gPAResult->pasteLinkSetting) {
                   // setup default radio buttons
                   CheckDlgButton(hWnd, IDD_PASTELINKCHKBOX, kODTrue);
               } else {
                   // deactivate 'Get updates' controls
                   HWND disableItem = GetDlgItem(hWnd, IDD_GETUPDATESTXT);
                   EnableWindow(disableItem, FALSE);
                   disableItem = GetDlgItem(hWnd, IDD_PASTEAUTOBTN);
                   EnableWindow(disableItem, FALSE);
                   disableItem = GetDlgItem(hWnd, IDD_PASTEMANUALBTN);
                   EnableWindow(disableItem, FALSE);
                   disableItem = GetDlgItem(hWnd, IDD_PASTELINKCHKBOX);
                   EnableWindow(disableItem, FALSE);

               }
               // set up Merge with Contents
	       if ((gMergeSetting == kODPasteAsEmbedOnly) || (gMergeSetting == kODPasteAsEmbed)) {
		  CheckDlgButton(hWnd, IDD_MERGEBTN, kODFalse);
		  CheckDlgButton(hWnd, IDD_EMBEDBTN, kODTrue);
		  gPAResult->mergeSetting = kODFalse;
	      } 
	       if ((gMergeSetting == kODPasteAsMergeOnly) || (gMergeSetting == kODPasteAsMerge)) {
		  CheckDlgButton(hWnd, IDD_MERGEBTN, kODTrue);
		  CheckDlgButton(hWnd, IDD_EMBEDBTN, kODFalse);
                  gPAResult->mergeSetting = kODTrue;
	       }
	       HWND disableItem;
	       if (gMergeSetting == kODPasteAsEmbedOnly) {
		  disableItem = GetDlgItem(hWnd, IDD_MERGEBTN);
	 	  EnableWindow(disableItem, FALSE);
	       }
	       if (gMergeSetting == kODPasteAsMergeOnly) {
		  disableItem = GetDlgItem(hWnd, IDD_EMBEDBTN);
	 	  EnableWindow(disableItem, FALSE);
	       }
          //     CheckDlgButton(hWnd, IDD_MERGEBTN, kODTrue);
          //     gPAResult->mergeSetting = kODTrue;

               SetWindowLong (hWnd, DWL_USER, lParam);

	       SetFocus(hWnd);

           }
           return FALSE;

       case WM_COMMAND:
           switch (wParam) {
               case IDOK:   // Final OK button ("Paste")
                   {
                   ODFacet   *facet   = (ODFacet*)GetWindowLong(hWnd, DWL_USER);
                   ODFrame   *frame   = facet->GetFrame(ev);
                   ODPart    *part    = frame->AcquirePart(ev);
                   ODWindow* window   = facet->GetWindow(ev);
                   ODSession* session = frame->GetStorageUnit(ev)->GetSession(ev);

                   // update Kind
                   ODSShort kindItem = (ODSShort) SendDlgItemMessage (hWnd, IDD_PARTKIND, CB_GETCURSEL, 0, 0);
                   ODType  oldKind, newKind;
                   // rrk 2 apr 96 signature changed..
                   //GetThisKindFromList( gKindItem, gKindList, &oldKind );
                   // rrk 20 may 96 add one to all these item indices.  Our indices are
                   // zero-origin, but the lists OpenDoc maintains are 1-origin.
                   oldKind = GetThisKindFromList( gKindItem+1, gKindList );

                   if (kindItem != gKindItem)
                   {
                       oldKind = GetThisKindFromList( gKindItem+1, gKindList );
                       newKind = GetThisKindFromList( kindItem +1, gKindList );
                   }
                   else
                   {
                       oldKind = GetThisKindFromList( gKindItem+1, gKindList );
                       newKind = GetThisKindFromList( gKindItem+1, gKindList );
                   }

                   gPAResult->selectedKind = newKind;

                   gPAResult->selectedView = SendDlgItemMessage (hWnd, IDD_EMBEDAS, CB_GETCURSEL, 0, 0L);

                   EndDialog (hWnd, 1);
                   }
                   return TRUE;

               case IDD_PASTELINKCHKBOX:
                   {

                     if ( IsDlgButtonChecked(hWnd,IDD_PASTELINKCHKBOX) )        // If "Paste with Link"
                     {
                       HWND disableItem = GetDlgItem(hWnd, IDD_GETUPDATESTXT);  // "Get Updates:" text
                       EnableWindow(disableItem, TRUE);
                       disableItem = GetDlgItem(hWnd, IDD_PASTEAUTOBTN);        // Automatic (radio button)
                       EnableWindow(disableItem, TRUE);
                       disableItem = GetDlgItem(hWnd, IDD_PASTEMANUALBTN);      // Manual    (radio button)
                       EnableWindow(disableItem, TRUE);
                       gPAResult->pasteLinkSetting = kODTrue;
                     }
                     else      // If normal paste (no link)
                     {
                       HWND disableItem = GetDlgItem(hWnd, IDD_GETUPDATESTXT);
                       EnableWindow(disableItem, FALSE);
                       disableItem = GetDlgItem(hWnd, IDD_PASTEAUTOBTN);
                       EnableWindow(disableItem, FALSE);
                       disableItem = GetDlgItem(hWnd, IDD_PASTEMANUALBTN);
                       EnableWindow(disableItem, FALSE);
                       gPAResult->pasteLinkSetting = kODFalse;
                     }
                   }
                   return FALSE;
                   break;
               case IDD_PASTEAUTOBTN:
                   gPAResult->autoUpdateSetting = kODTrue;
                   return FALSE;
                   break;
               case IDD_PASTEMANUALBTN:
                   gPAResult->autoUpdateSetting = kODFalse;
                   return FALSE;
                   break;
               case IDD_MERGEBTN:
                   gPAResult->mergeSetting = kODTrue;
                   return FALSE;
                   break;
               case IDD_EMBEDBTN:
                   gPAResult->mergeSetting = kODFalse;
                   return FALSE;
                   break;
               case IDCANCEL:
                   EndDialog (hWnd, 0);
                   gPAResult = kODNULL;
                   return TRUE;
		   break;
               case DID_HELP:
                   ODFacet   *facet   = (ODFacet*)GetWindowLong(hWnd, DWL_USER);
                   ODFrame   *frame   = facet->GetFrame(ev);
                   ODSession* session = frame->GetStorageUnit(ev)->GetSession(ev);
                   ODHelp   * helpme  = session->GetHelp(ev);
                   helpme->DisplayHelp(ev,ODHELPFILE,IDMS_EDIT_PASTEAS_PANEL);
                   break;
           }
           return TRUE;
	   break;
       case WM_HELP:
           ODFacet   *facet   = (ODFacet*)GetWindowLong(hWnd, DWL_USER);
           ODFrame   *frame   = facet->GetFrame(ev);
           ODSession* session = frame->GetStorageUnit(ev)->GetSession(ev);
           ODHelp   * helpme  = session->GetHelp(ev);
           helpme->DisplayHelp(ev,ODHELPFILE,IDMS_EDIT_PASTEAS_PANEL);
           break;
   }


   return FALSE;

}


//------------------------------------------------------------------------------
// GetBestKindAndSize
#ifdef DEFECT_22109
// note:  Will want to use GetUserKindForKind here when 22109 is resolved.
#endif
//------------------------------------------------------------------------------
ODStatic void GetBestKindAndSize(ODStorageUnit* contentSU, ODType* kind, ODULong* size)
{
   Environment* ev = somGetGlobalEnvironment();

   if (contentSU->Exists(ev, kODPropContents, (ODValueType)kODNULL, 1))
   {
       contentSU->Focus(ev, kODPropContents, kODPosUndefined, (ODValueType)kODNULL, 1, kODPosUndefined);
       *kind = contentSU->GetType(ev);
       *size = contentSU->GetSize(ev);
   }
   else
   {
       *kind = (ODType) kODNULL;
       *size = 0;
   }
}

//------------------------------------------------------------------------------
// GetDisplayKind
//------------------------------------------------------------------------------
ODStatic ISOString GetDisplayKind(ODType type, ODSession* session)
{
   Environment* ev = somGetGlobalEnvironment();
	   
   ISOString   theName;

   ODPartHandlerRegistryInt* odRegistry;
   odRegistry = session -> GetRegistry(ev);

   theName =  odRegistry->GetKindDisplayNameFromKind(ev, type);
   if ( (strcmp(theName, "GetKindDisplayName: No PartKind matches partKindName") != 0)
	&& (strcmp(theName, "GetKindDisplayName: No Parts found") != 0) ) {
        return(theName);
        }
   else {
        // No available editors support this type
        ODTranslation* translation = session->GetTranslation(ev);
        ODPlatformType platformType = translation->GetPlatformTypeFromISOType(ev, type);
        if ( platformType == kODNULL ) {
           return( catgets(ODcat_handle, LINKSPEC_SET, LINKSPEC_80, "No user kind"));
        }
        else {
#ifdef RRK_DEBUG
		   PRINT("RRK **** platformType is %d\t type is %s.\n", platformType, type);
#endif           
	  char    szUserKind[256];
	  memset(szUserKind,0,256);
	  if (!GetClipboardFormatName(platformType, szUserKind,255))

	     switch ( (UINT)platformType ) {
		case CF_TEXT:
			return(newString("TEXT"));
			break;					
		case CF_BITMAP:
			return(newString("BITMAP")); 
			break;					
		case CF_METAFILEPICT:
			return(newString("METAFILEPICT"));
			break;					
		case CF_SYLK:
			return(newString("SYLK"));
			break;					
		case CF_DIF:
			return(newString("DIF"));
			break;					
		case CF_TIFF:
			return(newString("TIFF"));
			break;					
		case CF_OEMTEXT:
			return(newString("OEMTEXT"));
			break;					
		case CF_DIB:
			return(newString("DIB"));
			break;					
		case CF_PALETTE:
			return(newString("PALETTE"));
			break;					
    		case CF_PENDATA:
			return(newString("PENDATA"));
			break;					
		case CF_RIFF:
			return(newString("RIFF"));
			break;					
		case CF_WAVE:
			return(newString("WAVE"));
			break;					
		case CF_UNICODETEXT:
			return(newString("UNICODETEXT"));
			break;					
		case CF_ENHMETAFILE:
		        return(newString("ENHMETAFILE"));
	      		break;					
	       	case CF_HDROP:
       			return(newString("HDROP"));
       			break;					
       		case CF_LOCALE:
			return(newString("LOCALE"));
	      		break;					
       	        default:
		        return( catgets(ODcat_handle, LINKSPEC_SET, LINKSPEC_80, "No user kind"));
	      		break;
       	      }
	  else
	    return(newString(szUserKind));
	}
   }
}

//------------------------------------------------------------------------------
// LinkSourceInfoDlgProc
//------------------------------------------------------------------------------
BOOL CALLBACK LinkSourceInfoDlgProc (HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
   Environment *ev = somGetGlobalEnvironment();
   static ODNameSpaceManager* nsm;
   HWND disableItem, enableItem;

   ODBoolean needsUpdate;
   static ODBaseLinkSource* linkSource;
   static wchar_t wcsDate[kODDateLength] = L"";
   char* mbsDate;
   
   switch (Message) {
       case WM_INITDIALOG:
           {
               linkSource = (ODBaseLinkSource*)lParam;

               ODLinkKey key;
               if (linkSource->Lock(ev, 0, &key))
               {
                 TRY
                   ODStorageUnit *contentSU = linkSource->GetContentStorageUnit(ev, key);

                   // set the Kind
                   ODULong kindLen;
                   ODType  kind;
                   GetBestKindAndSize(contentSU, &kind, &kindLen);
                   if (kind)  // was kindLen - rrk 28feb97
                       SetDlgItemText (hWnd, IDD_LSKINDTXT, GetDisplayKind(kind, gSession));

                   // set up created

                   time_t theTime = ODGetCreationDate(ev, ODGetSUFromPstObj(ev, linkSource));
		   if (theTime)
		     {
		       char* dateFormat = nl_langinfo(D_T_FMT); 
		       struct tm *timeptr = localtime((const time_t*) &theTime);

		       wchar_t wcsDateFormat [kODDateLength * kODWcsLength];
		       mbstowcs (wcsDateFormat, dateFormat, kODDateLength * kODWcsLength);
		       wcsftime(wcsDate, kODDateLength*kODWcsLength, wcsDateFormat, timeptr);
		       mbsDate = (char*) malloc (kODDateLength*kODWcsLength);
		       wcstombs(mbsDate, wcsDate, kODDateLength*kODWcsLength);
		       SetDlgItemText (hWnd, IDD_LSCREATEDTXT,(LPCSTR) mbsDate);
		       free(mbsDate);
		     }


                   // set up modified
                   theTime = linkSource->GetChangeTime(ev);
		   if (theTime)
		     {
		       char* dateFormat = nl_langinfo(D_T_FMT); 
		       struct tm *timeptr = localtime((const time_t*) &theTime);

		       wchar_t wcsDateFormat [kODDateLength * kODWcsLength];
		       mbstowcs (wcsDateFormat, dateFormat, kODDateLength * kODWcsLength);
		       wcsftime(wcsDate, kODDateLength*kODWcsLength, wcsDateFormat, timeptr);
		       mbsDate = (char*) malloc (kODDateLength*kODWcsLength);
		       wcstombs(mbsDate, wcsDate, kODDateLength*kODWcsLength);
		       SetDlgItemText (hWnd, IDD_LSUPDATEDTXT,(LPCSTR) mbsDate);
		       free(mbsDate);
		     }

                 CATCH_ALL
                       linkSource->Unlock(ev, key);
                       RERAISE;
                 ENDTRY
                 linkSource->Unlock(ev, key);
               }	
	
	       needsUpdate = (gUpdateID == kODUnknownUpdate) || (gUpdateID != linkSource->GetUpdateID(ev));
			
	       gLIResult->autoUpdate = linkSource->IsAutoUpdate(ev);
               CheckDlgButton(hWnd, IDD_LSONSAVEBTN, gLIResult->autoUpdate);
               CheckDlgButton(hWnd, DID_LSMANUALLYBTN, !(gLIResult->autoUpdate));

	       // Disable Update Now button if updates are automatic or link is up to date.
	       if ( gLIResult->autoUpdate || !needsUpdate )
		  {
                   disableItem = GetDlgItem(hWnd, DID_LSUPDATENOWBTN);
                   EnableWindow(disableItem, FALSE);
	          }else{
                   enableItem = GetDlgItem(hWnd, DID_LSUPDATENOWBTN);
                   EnableWindow(enableItem, TRUE);
                  }
// bogus for now
//               if (gLIResult){ // deactivate update now button
//                   disableItem = GetDlgItem(hWnd, DID_LSUPDATENOWBTN);
//                   EnableWindow(disableItem, FALSE);
//                   CheckDlgButton(hWnd, IDD_LSONSAVEBTN, kODTrue);
//                   gLIResult->autoUpdate = kODTrue;
//               }else{
//                   CheckDlgButton(hWnd, IDD_PASTEMANUALBTN, kODTrue);
//                 gLIResult->autoUpdate = kODFalse;
//               }

               SetWindowLong (hWnd, DWL_USER, lParam);

               // Disable some items if changes are not allowed or draft is read only
	       if ( !gChangesAllowed || DraftIsReadOnly(ev, linkSource->GetStorageUnit(ev)) )
		 {
                   disableItem = GetDlgItem(hWnd, DID_LSUPDATENOWBTN);
                   EnableWindow(disableItem, FALSE);
                   disableItem = GetDlgItem(hWnd, DID_LSBREAKLINKBTN);
                   EnableWindow(disableItem, FALSE);
                   disableItem = GetDlgItem(hWnd, IDD_LSONSAVEBTN);
                   EnableWindow(disableItem, FALSE);
                   disableItem = GetDlgItem(hWnd, DID_LSMANUALLYBTN);
                   EnableWindow(disableItem, FALSE);
//                   CheckDlgButton(hWnd, IDD_LSONSAVEBTN, kODFalse);
//                   CheckDlgButton(hWnd, IDD_LSPASTEMANUALBTN, kODFalse);
		 }
	       SetFocus(hWnd);
           }
           return FALSE;

       case WM_COMMAND:
           switch (wParam) {
               case IDOK:
                   gLIResult->action = kODLinkInfoOk;
                   EndDialog (hWnd, 1);
                   return TRUE;

               case IDD_LSONSAVEBTN:
                   gLIResult->autoUpdate = kODTrue;
                   disableItem = GetDlgItem(hWnd, DID_LSUPDATENOWBTN);
                   EnableWindow(disableItem, FALSE);
                   return FALSE;

               case DID_LSMANUALLYBTN:
                   gLIResult->autoUpdate = kODFalse;	
		   needsUpdate = (gUpdateID == kODUnknownUpdate) || (gUpdateID != linkSource->GetUpdateID(ev));
		   if (needsUpdate) {
		     enableItem = GetDlgItem(hWnd, DID_LSUPDATENOWBTN);
		     EnableWindow(enableItem, TRUE);
		   }
                   return FALSE;

               case IDCANCEL:
                   EndDialog (hWnd, 0);
                   gLIResult = kODNULL;
                   return TRUE;

               case DID_LSBREAKLINKBTN:
                   gLIResult->action = kODLinkInfoBreakLink;
                   EndDialog (hWnd, 1);
                   return TRUE;

               case DID_LSUPDATENOWBTN:
                   gLIResult->action = kODLinkInfoUpdateNow;
                   EndDialog (hWnd, 1);
                   return TRUE;

               case DID_HELP:
                                // We need to get a handle to the session object here...
                   ODFrame   *frame   = gFacet->GetFrame(ev);
                   ODSession* session = frame->GetStorageUnit(ev)->GetSession(ev);
                   ODHelp   * helpme  = session->GetHelp(ev);
                   helpme->DisplayHelp(ev,ODHELPFILE,IDD_LSPAGEDLG_PANEL);
                   break;
           }
           return TRUE;
	   break;
       case WM_HELP:
           // We need to get a handle to the session object here...
           ODFrame   *frame   = gFacet->GetFrame(ev);
           ODSession* session = frame->GetStorageUnit(ev)->GetSession(ev);
           ODHelp   * helpme  = session->GetHelp(ev);
           helpme->DisplayHelp(ev,ODHELPFILE,IDD_LSPAGEDLG_PANEL);
           break;
   }


   return FALSE;

}


//------------------------------------------------------------------------------
// LinkDestInfoDlgProc
//------------------------------------------------------------------------------
BOOL CALLBACK LinkDestInfoDlgProc (HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
   Environment *ev = somGetGlobalEnvironment();

   ODBoolean needsUpdate;
   HWND disableItem, enableItem;
   static ODLinkInfo* info;

   static wchar_t wcsDate[kODDateLength] = L"";
   char* mbsDate;

   switch (Message) {
       case WM_INITDIALOG:
           {
               info = (ODLinkInfo*)lParam;

               // set the Kind
               SetDlgItemText (hWnd, IDD_LDKINDTXT, GetDisplayKind(info->kind, gSession));

               // set up created
               time_t theTime = info->creationTime;
	       if (theTime)
		 {
		   char* dateFormat = nl_langinfo(D_T_FMT); 
	           struct tm *timeptr = localtime((const time_t*) &theTime);

		   wchar_t wcsDateFormat [kODDateLength * kODWcsLength];
	           mbstowcs (wcsDateFormat, dateFormat, kODDateLength * kODWcsLength);
	           wcsftime(wcsDate, kODDateLength*kODWcsLength, wcsDateFormat, timeptr);
	           mbsDate = (char*) malloc (kODDateLength*kODWcsLength);
	           wcstombs(mbsDate, wcsDate, kODDateLength*kODWcsLength);
	           SetDlgItemText (hWnd, IDD_LDCREATEDTXT,(LPCSTR) mbsDate);
	           free(mbsDate);
	         }

               // set up modified
               theTime = info->changeTime;
	       if (theTime)
		 {
		   char* dateFormat = nl_langinfo(D_T_FMT); 
	           struct tm *timeptr = localtime((const time_t*) &theTime);

		   wchar_t wcsDateFormat [kODDateLength * kODWcsLength];
	           mbstowcs (wcsDateFormat, dateFormat, kODDateLength * kODWcsLength);
	           wcsftime(wcsDate, kODDateLength*kODWcsLength, wcsDateFormat, timeptr);
	           mbsDate = (char*) malloc (kODDateLength*kODWcsLength);
	           wcstombs(mbsDate, wcsDate, kODDateLength*kODWcsLength);
	           SetDlgItemText (hWnd, IDD_LDUPDATEDTXT,(LPCSTR) mbsDate);
	           free(mbsDate);
	         }

	       needsUpdate = (info->change == kODUnknownUpdate) || (info->change != gLink->GetUpdateID(ev));
		
	       gLIResult->autoUpdate = info->autoUpdate;
               CheckDlgButton(hWnd, IDD_LDAUTOMATICALLYBTN, gLIResult->autoUpdate);
               CheckDlgButton(hWnd, DID_LDMANUALLYBTN, !(gLIResult->autoUpdate)); 

		// Disable Update Now button if updates are automatic or destination is up to date.
	       if ( info->autoUpdate || !needsUpdate ) {
// bogus for now
               //if (gLIResult){ // deactivate update now button
                   disableItem = GetDlgItem(hWnd, DID_LDUPDATENOWBTN);
                   EnableWindow(disableItem, FALSE);

                }else{
                   enableItem = GetDlgItem(hWnd, DID_LDUPDATENOWBTN);
                   EnableWindow(enableItem, TRUE);

               }

               SetWindowLong (hWnd, DWL_USER, lParam);

               // Disable some items if changes are not allowed or draft is read only
	       if ( !gChangesAllowed || DraftIsReadOnly(ev, gLink->GetStorageUnit(ev)) )
		 {
                   disableItem = GetDlgItem(hWnd, DID_LDUPDATENOWBTN);
                   EnableWindow(disableItem, FALSE);
                   disableItem = GetDlgItem(hWnd, DID_LDBREAKLINKBTN);
                   EnableWindow(disableItem, FALSE);
                   disableItem = GetDlgItem(hWnd, IDD_LDAUTOMATICALLYBTN);
                   EnableWindow(disableItem, FALSE);
                   disableItem = GetDlgItem(hWnd, DID_LDMANUALLYBTN);
                   EnableWindow(disableItem, FALSE);
//                   CheckDlgButton(hWnd, IDD_LSONSAVEBTN, kODFalse);
//                   CheckDlgButton(hWnd, IDD_LSPASTEMANUALBTN, kODFalse);
		}
	       SetFocus(hWnd);
           }
           return FALSE;

       case WM_COMMAND:
           switch (wParam) {
               case IDOK:
                   gLIResult->action = kODLinkInfoOk;
                   EndDialog (hWnd, 1);
                   return TRUE;

               case IDD_LDAUTOMATICALLYBTN:
                   gLIResult->autoUpdate = kODTrue;
                   disableItem = GetDlgItem(hWnd, DID_LDUPDATENOWBTN);
                   EnableWindow(disableItem, FALSE);
                   return FALSE;

               case DID_LDMANUALLYBTN:
                   gLIResult->autoUpdate = kODFalse;
	           needsUpdate = (info->change == kODUnknownUpdate) || (info->change != gLink->GetUpdateID(ev));
		   if (needsUpdate) {
		     enableItem = GetDlgItem(hWnd, DID_LDUPDATENOWBTN);
		     EnableWindow(enableItem, TRUE);
		   }
                   return FALSE;

               case IDCANCEL:
                   EndDialog (hWnd, 0);
                   gLIResult = kODNULL;
                   return TRUE;

               case DID_LDBREAKLINKBTN:
                   gLIResult->action = kODLinkInfoBreakLink;
                   EndDialog (hWnd, 1);
                   return TRUE;

               case DID_LDUPDATENOWBTN:
                   gLIResult->action = kODLinkInfoUpdateNow;
                   EndDialog (hWnd, 1);
                   return TRUE;

               case IDD_LDFINDSOURCEBTN:
	           gLIResult->action = kODLinkInfoFindSource;
                   EndDialog (hWnd, 1);
                   return TRUE;

               case DID_HELP:
                   // We need to get a handle to the session object here...
                   ODFrame   *frame   = gFacet->GetFrame(ev);
                   ODSession* session = frame->GetStorageUnit(ev)->GetSession(ev);
                   ODHelp   * helpme  = session->GetHelp(ev);
                   helpme->DisplayHelp(ev,ODHELPFILE,IDD_LTPAGEDLG_PANEL);
                   break;
           }
           return TRUE;
	   break;
       case WM_HELP:
           // We need to get a handle to the session object here...
           ODFrame   *frame   = gFacet->GetFrame(ev);
           ODSession* session = frame->GetStorageUnit(ev)->GetSession(ev);
           ODHelp   * helpme  = session->GetHelp(ev);
           helpme->DisplayHelp(ev,ODHELPFILE,IDD_LTPAGEDLG_PANEL);
           break;
   }


   return FALSE;

}

//------------------------------------------------------------------------------
// ShowLinkUpdateAlert
//------------------------------------------------------------------------------

ODBoolean ShowLinkUpdateAlert( HWND hwnd)
{

   Environment *ev = somGetGlobalEnvironment();

   gAlertResult = kLinkUpdateStopBtn;

   // Load the resource file
   HINSTANCE resInstance = LoadLibrary("ODRES.DLL");

   DialogBoxParam (resInstance, MAKEINTRESOURCE(IDD_LUDLG), hwnd, (DLGPROC)LinkUpdateAlertDlgProc, (LPARAM)0);

   return (gAlertResult == kLinkUpdateContinueBtn);
}

//------------------------------------------------------------------------------
// LinkUpdateAlertDlgProc
//------------------------------------------------------------------------------
BOOL CALLBACK LinkUpdateAlertDlgProc (HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
   Environment *ev = somGetGlobalEnvironment();
   static ODNameSpaceManager* nsm;

   switch (Message) {
       case WM_INITDIALOG:
           {
               SetWindowLong (hWnd, DWL_USER, lParam);
	       SetFocus(hWnd);
           }
           return FALSE;

       case WM_COMMAND:
           switch (wParam) {
               case IDD_LUUPDATE:
                       gAlertResult = kLinkUpdateContinueBtn;
                   EndDialog (hWnd, 1);
                   return TRUE;

               case IDD_LUSTOP:
                       gAlertResult = kLinkUpdateStopBtn;
                   EndDialog (hWnd, 1);
                   return TRUE;

           }
           return TRUE;
   }


   return FALSE;

}

//------------------------------------------------------------------------------
// DraftIsReadOnly
//------------------------------------------------------------------------------
ODStatic ODBoolean DraftIsReadOnly(Environment* ev, ODStorageUnit* su)
{
	return (!HAS_WRITE_ACCESS(su->GetDraft(ev)->GetPermissions(ev)));
}
