//====START_GENERATED_PROLOG======================================
//
//
//   COMPONENT_NAME: odother
//
//   CLASSES: none
//
//   ORIGINS: 27
//
//
//   (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.7 nt/src/samples/JavaPart/iodjava.cpp, odjavapart, od96nt, odnt9714c 3/24/97 16:09:55 [ 4/2/97 17:54:48 ]

#ifndef SOM_Module_JavaPart_Source
#define SOM_Module_JavaPart_Source
#endif

#ifndef _ALTPOINT_
#include <AltPoint.h>                   // Use C++ savvy ODPoint and ODRect
#endif

#define JavaPart_Class_Source
#define VARIABLE_MACROS

#ifndef _ODEXCEPT_
#include <ODExcept.h>
#endif

#ifndef SOM_ODStorageUnit_xh
#include <StorageU.xh>
#endif

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

#ifndef SOM_JavaPart_xih
#include "IODJava.xih"
#endif

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

#ifndef SOM_ODWindowState_xh
#include <WinStat.xh>
#endif

#ifndef SOM_ODShape_xh
#include <Shape.xh>
#endif

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

#ifndef SOM_ODFrameFacetIterator_xh
#include <FrFaItr.xh>
#endif

#ifndef _TEMPOBJ_
#include <TempObj.h>
#endif

#ifndef SOM_ODMenuBar_xh
#include <MenuBar.xh>
#endif

#ifndef SOM_ODTransform_xh
#include <Trnsform.xh>
#endif

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

#include <StdTypIO.h>
#include <ODRes.h>

extern "C" {
	#include "JEmpower.h"
}

#ifndef IBMSample_JAVAPART
#include "IODJava.h"
#endif

#ifndef IBMSample_TAG
#include "Tag.h"
#endif

#ifndef IBMSample_APPLET
#include "Applet.h"
#endif

#ifndef IBMSample_BEAN
#include "Bean.h"
#endif

#ifndef IBMSample_PROPERTIESDIALOG
#include "PropDlg.h"
#endif

#ifndef IBMSample_PREFERENCESDIALOG
#include "PrefDlg.h"
#endif

#ifndef IBMSample_MISC
#include "Misc.h"
#endif

#include <string.h>
#include <FocusLib.h>
#include <StorUtil.h>


/*
 *  Meta Class constants...
 */
const ODType   kJavaPartKind            = "JavaPart";
const ODType   kJavaPartKindDisplayName = "Java Part";
const ODType   kJavaPartHandlerName     = "JavaPart";
const ODType   kJavaPartCategory        = "OpenDoc:Category:Sample";

#define kJavaByteValue "JavaByteValue"


#define CMD(X)    kODCommand##X
#define CMD_Offset                   MENUID_ACTIVEPART_USER
#define CMD_Offset_Subclass          (CMD_Offset+500)

#define kODJavaPartMenuID            (CMD_Offset_Subclass + 0)
#define kODCommandLoadApplet         (CMD_Offset_Subclass + 1)
#define kODCommandAppletProperties   (CMD_Offset_Subclass + 2)
#define kODCommandSeparator          (CMD_Offset_Subclass + 3)
#define kODCommandConsole            (CMD_Offset_Subclass + 4)
#define kODCommandStart              (CMD_Offset_Subclass + 5)
#define kODCommandStop               (CMD_Offset_Subclass + 6)
#define kODCommandSeparator2         (CMD_Offset_Subclass + 7)
#define kODCommandPreferences        (CMD_Offset_Subclass + 8)
#define kODCommandLoadBean           (CMD_Offset_Subclass + 9)

/*
 *  Helper function prototypes...
 */
void WriteAppletTagToStorage (Environment* ev, ODStorageUnit* su, AppletTag* tag);
AppletTag* ReadAppletTagFromStorage (Environment* ev, ODStorageUnit* su);

void WriteBeanTagToStorage (Environment* ev, ODStorageUnit* su, BeanTag* tag);
BeanTag* ReadBeanTagFromStorage (Environment* ev, ODStorageUnit* su);


/*-------------------------------------------------------------------+
|                              Log ()                                |
| ================================================================== |
|                                                                    |
| Function:    This function will output a message to the utility    |
|              mgsdisp.exe for MethodDebug call.  This allows the    |
|              developer to see the OpenDoc method calls being made  |
|              to this part in real-time.                            |
|                                                                    |
| Note(s):     This function only exists if DEBUG is defined.        |
|                                                                    |
| Parameters:  char *c;    description of class                      |
|              char *m;    description of method                     |
|                                                                    |
| Returns:     none                                                  |
|                                                                    |
+-------------------------------------------------------------------*/
#ifdef DEBUG
	#include <qprintf.h>

	#undef JavaPartMethodDebug
	#undef M_JavaPartMethodDebug

	#define JavaPartMethodDebug(c,m) Log(c,m)
	#define M_JavaPartMethodDebug(c,m) Log(c,m)

	static void Log(char* className, char* methodName)
	{
		qprintf ("%s::%s\n", className, methodName);
	}
#endif



/*-------------------------------------------------------------------+
|                       JavaPart::InitPart ()                        |
| ================================================================== |
|                                                                    |
| Function:    Initialize the JavaPart.                              |
|                                                                    |
| Algorithm:   o  Initialize parent part (SimplePart)                |
|              o  Initialize all instance data                       |
|                                                                    |
| Parameters:  storageUnit - empty storage unit                      |
|              partWrapper - part wrapper                            |
|                                                                    |
+-------------------------------------------------------------------*/
SOM_Scope void SOMLINK JavaPartInitPart(
	JavaPart*	somSelf,
	Environment*	ev,
	ODStorageUnit*	storageUnit,
	ODPart*		partWrapper)
{
	JavaPartData*	somThis = JavaPartGetData(somSelf);
	JavaPartMethodDebug("JavaPart","InitPart");

	/*
	 *  Initialize all instance data...
	 */
	_fApplet      = kODNULL;
	_fFacet       = kODNULL;
	_fMenuBar     = kODNULL;

	/*
	 *  Initialize our parent part...
	 */
	JavaPart_parent_SimplePart_InitPart (somSelf, ev, storageUnit, 
					    partWrapper);
	_fPartWrapper = partWrapper;
	_fAppletTag   = new AppletTag ((char*) GetDefaultURL ());
}


/*-------------------------------------------------------------------+
|                 JavaPart::InitPartFromStorage ()                   |
| ================================================================== |
|                                                                    |
| Function:    Initialize the JavaPart from storage.                 |
|                                                                    |
| Algorithm:   o  Initialize parent part (SimplePart)                |
|              o  Initialize instance data and persistent values     |
|                 from the storage unit.                             |
|                                                                    |
| Parameters:  storageUnit - storage unit containing persistent data |
|              partWrapper - part wrapper                            |
|                                                                    |
+-------------------------------------------------------------------*/
SOM_Scope void SOMLINK JavaPartInitPartFromStorage(
	JavaPart*	somSelf,
	Environment*	ev,
	ODStorageUnit*	storageUnit,
	ODPart*		partWrapper)
{
	JavaPartData*	somThis = JavaPartGetData(somSelf);
	JavaPartMethodDebug("JavaPart","InitPartFromStorage");

	/*
	 *  Initialize instance data...
	 */
	_fApplet      = kODNULL;
	_fFacet       = kODNULL;
	_fMenuBar     = kODNULL;

	/*
	 *  Initialize our parent part...
	 */
	JavaPart_parent_SimplePart_InitPartFromStorage (somSelf, ev, 
						storageUnit, partWrapper);

	_fPartWrapper = partWrapper;
	_fAppletTag   = ReadAppletTagFromStorage (ev, storageUnit);
	_fBeanTag     = ReadBeanTagFromStorage (ev, storageUnit);
}


/*-------------------------------------------------------------------+
|                     JavaPart::InstallMenus ()                      |
| ================================================================== |
|                                                                    |
| Function:    Add the JavaPart part specific menus.                 |
|                                                                    |
|              Adds the following to the main menu bar:              |
|                                                                    |
|                  Java                                              |
|                      Load Applet                                   |
|                      Load Bean                                     |
|                      Show console                                  |
|                      Start Applet                                  |
|                      Stop Applet                                   |
|                      Preferences                                   |
|                                                                    |
| Algorithm:   o  Obtain the OpenDoc menu bar                        |
|              o  Add the part specific menus                        |
|                                                                    |
+-------------------------------------------------------------------*/
SOM_Scope void  SOMLINK JavaPartInstallMenus (
	JavaPart*	somSelf,
	Environment*	ev)
{
	JavaPartData *somThis = JavaPartGetData(somSelf);
	JavaPartMethodDebug("JavaPart","JavaPartInstallMenus");

	try {
		/*
		 *  Obtain the menu bar...
		 */
		_fMenuBar = somSelf->GetMenuBar(ev);

		/*
		 *  Now add the JavaPart's menus...
		 */
		ODPlatformMenuItem *mi = new ODPlatformMenuItem;
		mi->afAttribute = 0;
		mi->id = kODJavaPartMenuID;

		ODPlatformMenu javaPartMenu = (ODPlatformMenu) CreateMenu ();
		_fMenuBar->AddMenuLast (ev, kODJavaPartMenuID, javaPartMenu, 
				   _fPartWrapper);
		_fMenuBar->SetMenuItemText(ev, ID_BASEMENUBAR, mi->id, "&Java");

#if 0 // Simplify for now...
		mi->id = CMD(AppletProperties);
		_fMenuBar->AddMenuItemLast(ev, kODJavaPartMenuID, kODNULL, mi);
		_fMenuBar->SetMenuItemText(ev, kODJavaPartMenuID, 
					mi->id, "Load Applet from URL...");
#endif

		mi->id = CMD(LoadApplet);
		_fMenuBar->AddMenuItemLast(ev, kODJavaPartMenuID, kODNULL, mi);
		_fMenuBar->SetMenuItemText(ev, kODJavaPartMenuID, 
					mi->id, "Load Applet...");

		mi->id = CMD(LoadBean);
		_fMenuBar->AddMenuItemLast(ev, kODJavaPartMenuID, kODNULL, mi);
		_fMenuBar->SetMenuItemText(ev, kODJavaPartMenuID, 
					mi->id, "Load Bean...");

		mi->id = kODCommandSeparator;
		mi->afAttribute = MF_SEPARATOR;
		_fMenuBar->AddMenuItemLast(ev, kODJavaPartMenuID, kODNULL, mi);

		mi->id = CMD(Console);
		_fMenuBar->AddMenuItemLast(ev, kODJavaPartMenuID, kODNULL, mi);
		_fMenuBar->SetMenuItemText(ev, kODJavaPartMenuID, 
					mi->id, "Show console");

		mi->id = CMD(Start);
		_fMenuBar->AddMenuItemLast(ev, kODJavaPartMenuID, kODNULL, mi);
		_fMenuBar->SetMenuItemText(ev, kODJavaPartMenuID, 
					mi->id, "Start Applet");

		mi->id = CMD(Stop);
		_fMenuBar->AddMenuItemLast(ev, kODJavaPartMenuID, kODNULL, mi);
		_fMenuBar->SetMenuItemText(ev, kODJavaPartMenuID, 
					mi->id, "Stop Applet");

		mi->id = kODCommandSeparator2;
		mi->afAttribute = MF_SEPARATOR;
		_fMenuBar->AddMenuItemLast(ev, kODJavaPartMenuID, kODNULL, mi);

		mi->id = CMD(Preferences);
		_fMenuBar->AddMenuItemLast(ev, kODJavaPartMenuID, kODNULL, mi);
		_fMenuBar->SetMenuItemText(ev, kODJavaPartMenuID, 
					mi->id, "Preferences");

		delete mi;

	} catch (ODException _exception) {
	}
}


/*-------------------------------------------------------------------+
|                     JavaPart::AdjustMenus ()                       |
| ================================================================== |
|                                                                    |
| Function:    Enable the JavaPart part specific menus.              |
|                                                                    |
| Algorithm:   o  Enable part specific menus                         |
|                                                                    |
| Parameters:  frame - reference to the display frame whoses menus   |
|                      are to be displayed.                          |
|                                                                    |
+-------------------------------------------------------------------*/
SOM_Scope void  SOMLINK JavaPartAdjustMenus (
	JavaPart*	somSelf,
	Environment*	ev,
	ODFrame*	frame)
{
	JavaPartData *somThis = JavaPartGetData(somSelf);
	JavaPartMethodDebug("JavaPart","JavaPartAdjustMenus");

	try {
		/*
		 *  Give parent class a chance to adjust the menus...
		 */
		JavaPart_parent_SimplePart_AdjustMenus (somSelf, ev, frame);

		/*
		 *  Enable our menu...
		 */
		if (_fMenuBar) {
			_fMenuBar->EnableMenuItem(ev, kODJavaPartMenuID, 
					CMD(AppletProperties), kODTrue);
			_fMenuBar->EnableMenuItem(ev, kODJavaPartMenuID, 
					CMD(LoadApplet), kODTrue);
			_fMenuBar->EnableMenuItem(ev, kODJavaPartMenuID, 
					CMD(LoadBean), kODTrue);
			_fMenuBar->EnableMenuItem(ev, kODJavaPartMenuID, 
					CMD(Console), kODTrue);
			_fMenuBar->EnableMenuItem(ev, kODJavaPartMenuID, 
					CMD(Start), _fIsApplet);
			_fMenuBar->EnableMenuItem(ev, kODJavaPartMenuID, 
					CMD(Stop), _fIsApplet);
			_fMenuBar->EnableMenuItem(ev, kODJavaPartMenuID, 
					CMD(Preferences), kODTrue);
		}
	} catch (ODException _exception) {
	}
}


/*-------------------------------------------------------------------+
|                      JavaPart::FacetAdded ()                       |
| ================================================================== |
|                                                                    |
| Function:    Create the JavaPart window when we are given the      |
|              first facet.                                          |
|                                                                    |
| Algorithm:   o  Obtain the OpenDoc menu bar                        |
|              o  Add the part specific menus                        |
|                                                                    |
| Parameters:  facet - facet that has been added                     |
|                                                                    |
+-------------------------------------------------------------------*/
SOM_Scope void  SOMLINK JavaPartFacetAdded (
	JavaPart*	somSelf,
	Environment*	ev, 
	ODFacet* 	facet)
{
	JavaPartMethodDebug("JavaPart","JavaPartFacetAdded");
	JavaPartData* somThis = JavaPartGetData (somSelf);

	/*
	 *  When the first facet is added, start the Java environment...
	 */
	if (_fFacet == kODNULL) {
		_fFacet = facet;

		/*
		 *  Check the environment to ensure that CLASSPATH is
		 *  set, ... etc.
		 */
		if (CheckEnvironment () == E_FAIL) return;

		if (_fAppletTag) {
			_fApplet = new Applet (somSelf, _fAppletTag);
			_fApplet->Init ();
			_fApplet->Start ();
		} /* endif */

		if (_fBeanTag) {
			_fBean = new Bean (somSelf, _fBeanTag);
			_fBean->Init();
		} /* endif */
	}
}


/*-------------------------------------------------------------------+
|                     JavaPart::FacetRemoved ()                      |
| ================================================================== |
|                                                                    |
| Function:    Destroy the JavaPart window when our facet is being   |
|              destroyed.                                            |
|                                                                    |
| Algorithm:   o  Delete the _fApplet or _fBean, causing their       |
|                 destructors to run, which call jeAppletDestroy()   |
|                 or jeBeanDispose(), removing the embedded window   |
|                                                                    |
| Parameters:  facet - facet that is been removed                    |
|                                                                    |
+-------------------------------------------------------------------*/
SOM_Scope void  SOMLINK JavaPartFacetRemoved (
	JavaPart*	somSelf,
	Environment*	ev, 
	ODFacet* 	facet)
{
	JavaPartMethodDebug("JavaPart","JavaPartFacetRemoved");
	JavaPartData* somThis = JavaPartGetData (somSelf);

      if (_fApplet) delete _fApplet;
      if (_fBean) delete _fBean;

      _fApplet = NULL;
      _fBean = NULL;
}


/*-------------------------------------------------------------------+
|                  JavaPart::FrameShapeChanged ()                    |
| ================================================================== |
|                                                                    |
| Function:    The frame that we are embedded in changed size, thus  |
|              resize the Applet/Bean.                               |
|                                                                    |
| Algorithm:   o  Resize the Applet/Bean                             |
|                                                                    |
| Parameters:  frame - frame that was reshaped                       |
|                                                                    |
+-------------------------------------------------------------------*/
SOM_Scope void SOMLINK JavaPartFrameShapeChanged(
	JavaPart*	somSelf,
	Environment*	ev,
	ODFrame*	frame)
{
	JavaPartMethodDebug("JavaPart","JavaPartFrameShapeChanged");
	JavaPartData* somThis = JavaPartGetData (somSelf);

	/*
	 *  Resize the Applet to that of the first frame..
	 */
	ODFacet* facet;
	ODFrameFacetIterator* facets = frame->CreateFacetIterator(ev);
	if (_fFacet && (facet = facets->First(ev)) != kODNULL)
	{
		SIZEL size;
		somSelf->GetFrameSize (ev, facet, &size);

		if (_fApplet != kODNULL)
			_fApplet->Resize (size.cx, size.cy);

		if (_fBean != kODNULL)
			_fBean->Resize (size.cx, size.cy);
	}
	delete facets;
}


/*-------------------------------------------------------------------+
|                     JavaPart::GetFrameSize ()                      |
| ================================================================== |
|                                                                    |
| Function:    Determine the size of the given facet's frame.        |
|                                                                    |
| Algorithm:   o  Use transforms to convert size to pixels..         |
|                                                                    |
| Parameters:  facet - the given facet                               |
|              size  - size of facet in pixels                       |
|                                                                    |
+-------------------------------------------------------------------*/
SOM_Scope void SOMLINK JavaPartGetFrameSize (
        JavaPart*	somSelf,
        Environment*    ev,
        ODFacet*	facet,
        SIZEL*		size)
{
	JavaPartMethodDebug("JavaPart","JavaPartGetFrameSize");
	JavaPartData* somThis = JavaPartGetData (somSelf);

        RECT rect;
        TempODShape shape = facet->GetFrame(ev)->AcquireFrameShape(ev, kODNULL);
        GetRgnBox (shape->GetRegion(ev), &rect);
        TempODTransform transform = 
		facet->GetWindow(ev)->GetRootFacet(ev)->AcquireExternalTransform(ev, kODNULL);

        Point pt;
        pt.x = rect.right - rect.left;
        pt.y = rect.bottom - rect.top;

        ODPoint physicalPoint(pt);
        transform->TransformPoint(ev, &physicalPoint);

        size->cx = physicalPoint.IntX();
        size->cy = physicalPoint.IntY();
}


/*-------------------------------------------------------------------+
|                     JavaPart::SetFrameSize ()                      |
| ================================================================== |
|                                                                    |
| Function:    Set the specified frame's size                        |
|                                                                    |
| Algorithm:   o  Use transforms to set the size based on pixels..   |
|                                                                    |
| Parameters:  facet - the given facet                               |
|              size  - size of facet in pixels                       |
|                                                                    |
+-------------------------------------------------------------------*/
SOM_Scope void SOMLINK JavaPartSetFrameSize(
	JavaPart*	somSelf,
	Environment*	ev,
	ODFrame*	frame,
	long		width,
	long		height)
{
	JavaPartData*	somThis = JavaPartGetData(somSelf);
	JavaPartMethodDebug("JavaPart","SetFrameSize");

	/*
	 *  No point in continuing of the frame is NULL...
	 */
	if (!frame) return;

	/*
       * jwa:  RequestFrameShape has no effect if we're the root part, so we
       *       just let ourselves know to conform to the current frame shape.
       *
       * Note: This fixes most of the problems of the applet not filling in
       *       the entire DocShell client area when its the root part.
	 */
      if (frame->IsRoot(ev)) {
         somSelf->FrameShapeChanged(ev, frame);
         return;
      } /* endif */

	POINT	WantOriginOffset;
	SIZE	WantSize;

	SIZEL szl;
	WantSize.cx = (int) width;
	WantSize.cy = (int) height;
	WantOriginOffset.x = 0;
	WantOriginOffset.y = 0;

	ODFacet* facet;
	ODFrameFacetIterator* facets = frame->CreateFacetIterator(ev);
	if ((facet = facets->First(ev)) != kODNULL)
	{
		TempODTransform transform = 
			facet->GetWindow(ev)->GetRootFacet(ev)->
			AcquireExternalTransform(ev, kODNULL);

		Point originPoint;
		originPoint.x = WantOriginOffset.x;
		originPoint.y = WantOriginOffset.y;

		ODPoint logicalOrigin(originPoint);
		transform->InvertPoint(ev, &logicalOrigin);

		Point wantsizePoint;
		wantsizePoint.x = WantSize.cx;
		wantsizePoint.y = WantSize.cy;

		ODPoint logicalWantsize(wantsizePoint);
		transform->InvertPoint(ev, &logicalWantsize);

		ODRect NewRectShape;

		NewRectShape.Set(logicalOrigin.x,
				 logicalOrigin.y,
				 logicalOrigin.x + logicalWantsize.x,
				 logicalOrigin.y + logicalWantsize.y);
		
		ODShape *wantShape = new ODShape;
		wantShape->InitShape(ev);

		wantShape->SetRectangle(ev, &NewRectShape);

		{
			TempODShape shape = 
				frame->AcquireUsedShape(ev, kODNULL);
			frame->Invalidate(ev, shape, kODNULL);
			frame->InvalidateActiveBorder(ev);
		}

		{
			TempODShape shape = 
				frame->AcquireUsedShape(ev, kODNULL);
			frame->RequestFrameShape(ev, wantShape, kODNULL);
			frame->Invalidate(ev, shape, kODNULL);
			frame->InvalidateActiveBorder(ev);
		}

		frame->ChangeUsedShape(ev, kODNULL, kODNULL);
	}
	delete facets;
}


/*-------------------------------------------------------------------+
|                      JavaPart::CloneInto ()                        |
| ================================================================== |
|                                                                    |
| Function:    Save our persistent data into another storage unit.   |
|                                                                    |
| Algorithm:   o  Clone our parent, then our self                    |
|                                                                    |
| Parameters:  key         - current cloning operation               |
|              storageUnit - destination storage unit                |
|              scope       - scope of cloning operation              |
|                                                                    |
+-------------------------------------------------------------------*/
SOM_Scope void  SOMLINK JavaPartCloneInto(
	JavaPart*	somSelf, 
	Environment*	ev,
	ODDraftKey	key,
	ODStorageUnit*	storageUnit,
	ODFrame*	scopeFrame)
{
	JavaPartData *somThis = JavaPartGetData(somSelf);

	try {
		/*
		 *  Clone parent part first...
		 */
		JavaPart_parent_SimplePart_CloneInto (somSelf, ev, key, 
						    storageUnit, scopeFrame);
		/*
		 *  If we have created an Applet, externalize it's tag,
		 *  else externalize the current Applet tag...
		 */
		AppletTag* appletTag = NULL;
		BeanTag* beanTag = NULL;

		if (_fApplet) 
			appletTag = _fApplet->GetAppletTag ();
		else if (_fAppletTag) 
			appletTag = _fAppletTag;

		if (_fBean) 
			beanTag = _fBean->GetBeanTag ();
		else if (_fBeanTag) 
			beanTag = _fBeanTag;

		if ((appletTag==NULL) && (beanTag==NULL))
			appletTag = new AppletTag();

		if (appletTag)
			WriteAppletTagToStorage (ev, storageUnit, appletTag);

		if (beanTag)
			WriteBeanTagToStorage (ev, storageUnit, beanTag);

	} catch(ODException _exception) {
	}
}


/*-------------------------------------------------------------------+
|                     JavaPart::Externalize ()                       |
| ================================================================== |
|                                                                    |
| Function:    Save our persistent data.                             |
|                                                                    |
| Algorithm:   o  Save all of our persistent data                    |
|                                                                    |
+-------------------------------------------------------------------*/
SOM_Scope void  SOMLINK JavaPartExternalize (
	JavaPart*	somSelf,
        Environment*	ev)
{
	JavaPartData *somThis = JavaPartGetData(somSelf);
	JavaPartMethodDebug("JavaPart","JavaPartExternalize");

	try {
		JavaPart_parent_SimplePart_Externalize(somSelf, ev);

		ODStorageUnit* storageUnit = somSelf->GetStorageUnit(ev);

		/*
		 *  If we have created an Applet, externalize it's tag,
		 *  else externalize the current Applet tag...
		 */
		AppletTag* appletTag = NULL;
		BeanTag* beanTag = NULL;

		if (_fApplet) 
			appletTag = _fApplet->GetAppletTag ();
		else if (_fAppletTag) 
			appletTag = _fAppletTag;

		if (_fBean) 
			beanTag = _fBean->GetBeanTag ();
		else if (_fBeanTag) 
			beanTag = _fBeanTag;

		if ((appletTag==NULL) && (beanTag==NULL))
			appletTag = new AppletTag();

		if (appletTag)
			WriteAppletTagToStorage (ev, storageUnit, appletTag);

		if (beanTag)
			WriteBeanTagToStorage (ev, storageUnit, beanTag);

	} catch(ODException _exception) {
	}
}

/*-------------------------------------------------------------------+
|                     JavaPart::HandleEvent ()                       |
| ================================================================== |
|                                                                    |
| Function:    Process all of the event messages.                    |
|                                                                    |
| Algorithm:   o  Save all of our persistent data                    |
|                                                                    |
| Parameters:  event     - the event                                 |
|              frame     - display frame in which event might have   |
|                          occurred                                  |
|              facet     - facet in which event occured or KODNULL   |
|                          if the event was not based on geometry    |
|              eventInfo - additional event information              |
|                                                                    |
| Returns:     (TRUE)  Event was handled                             |
|              (FALSE) Event was NOT handled                         |
|                                                                    |
+-------------------------------------------------------------------*/
SOM_Scope ODBoolean SOMLINK JavaPartHandleEvent(
	JavaPart*	somSelf,
	Environment*	ev,
	ODEventData*	event,
	ODFrame*	frame,
	ODFacet*	facet,
	ODEventInfo*	eventInfo)
{
	JavaPartData*	somThis = JavaPartGetData(somSelf);
	JavaPartMethodDebug("JavaPart","HandleEvent");

	/*
	 *  Give parent part a chance to handle the message...
	 */
	ODBoolean tWasHandled = JavaPart_parent_SimplePart_HandleEvent (
					somSelf, ev, event, 
					frame, facet, eventInfo);
	if (tWasHandled == kODTrue) return tWasHandled;

	TempODWindow window = frame->AcquireWindow (ev);
	HWND partWindow = window->GetPlatformWindow (ev);

	switch (event->message) {

	case WM_MOUSEACTIVATE :
		tWasHandled = kODTrue;

		somSelf->Activate (ev, facet);
		break;

	case WM_COMMAND:

		switch (LOWORD(event->wParam)) {

		case CMD(AppletProperties):
			tWasHandled = kODTrue;
			if (_fApplet)
			{
				if (_fApplet == NULL) break;

				AppletTag* tag = 
					new AppletTag (*_fApplet->GetAppletTag ());

				PropertiesDialog dialog (partWindow);

				if (dialog.Get (tag)) {

					if (_fApplet) delete _fApplet;

					_fApplet = new Applet (somSelf, tag);
					_fApplet->Init ();
					_fApplet->Start ();
				}
			}
			break;

		case CMD(LoadApplet):
			tWasHandled = kODTrue;
			if (_fApplet || _fBean)
			{
				AppletTag* tag = SelectApplet ("Select an Applet");
				if (tag) {
					_fIsApplet = kODTrue;
					if (_fApplet) {
						delete _fApplet;
					} /* endif */
                              
					if (_fBean) {
						delete _fBean;
						_fBean = kODNULL;
						_fBeanTag = kODNULL;
					} /* endif */

					_fApplet = new Applet (somSelf, tag);
					_fApplet->Init ();
					_fApplet->Start ();
				}
			}
			break;

		case CMD(LoadBean):
			tWasHandled = kODTrue;
			if (_fApplet || _fBean)
			{
				BeanTag* tag = SelectBean (partWindow);
				if (tag) {
					_fIsApplet = kODFalse;
					if (_fApplet) {
						delete _fApplet;
						_fApplet = kODNULL;
						_fAppletTag = kODNULL;
					} /* endif */
                              
					if (_fBean) {
						delete _fBean;
					} /* endif */

					_fBean = new Bean (somSelf, tag);
					_fBean->Init();
				} /* endif */
                        } /* endif */
			break;

		case CMD(Preferences):
			tWasHandled = kODTrue;
			{
				PreferencesDialog dialog (partWindow);
				dialog.Show ();
			}
			break;

		case CMD(Console):
			tWasHandled = kODTrue;

			if (_fApplet) _fApplet->ShowConsole ();
			if (_fBean) _fBean->ShowConsole ();
			break;

		case CMD(Start):
			tWasHandled = kODTrue;

			if (_fApplet) _fApplet->Start ();
			break;

		case CMD(Stop):
			tWasHandled = kODTrue;

			if (_fApplet) _fApplet->Stop ();
			break;
		default:
			break;
		}
		break;

	default:
		break;
	}

	return tWasHandled;
}


/*-------------------------------------------------------------------+
|                         Helper Functions                           |
+-------------------------------------------------------------------*/


/*-------------------------------------------------------------------+
|                         WriteLongProp ()                           |
| ================================================================== |
|                                                                    |
| Function:    Helper function...  Writes a Property Value pair into |
|              the given storage unit.                               |
|                                                                    |
| Algorithm:   o  Add a property and set it's value                  |
|                                                                    |
| Parameters:  storageUnit - a storage unit                          |
|              propName    - property name                           |
|              size        - size of value                           |
|              value       - value                                   |
|                                                                    |
+-------------------------------------------------------------------*/
void WriteLongProp (
	Environment*	ev, 
	ODStorageUnit*	storageUnit, 
	char*		propName, 
	long 		value)
{
	storageUnit->AddProperty (ev, propName)-> AddValue (ev, kJavaByteValue);

	StorageUnitSetValue (storageUnit, ev, sizeof (ODULong), &value);
}


/*-------------------------------------------------------------------+
|                          ReadLongProp ()                           |
| ================================================================== |
|                                                                    |
| Function:    Helper function...  Reads a Property Value pair from  |
|              a given storage unit.                                 |
|                                                                    |
| Algorithm:   o  Focus in on the property value pair (if they exist)|
|                 and read the value.                                |
|                                                                    |
| Parameters:  storageUnit - a storage unit                          |
|              propName    - property name                           |
|              valueOut    - value read from storage unit            |
|                                                                    |
+-------------------------------------------------------------------*/
void ReadLongProp (
	Environment*	ev, 
	ODStorageUnit*	storageUnit, 
	char*		propName,	
	long&		valueOut)
{
	ODULong size;

	if (storageUnit->Exists(ev, propName, kJavaByteValue, 0)) {
		storageUnit->Focus (ev, propName, kODPosUndefined, 
				    kJavaByteValue, (ODValueIndex)0, 
				    kODPosFirstSib);

		StorageUnitGetValue (storageUnit, ev, sizeof (ODULong), &valueOut);
	}
}


/*-------------------------------------------------------------------+
|                        WriteStringProp ()                          |
| ================================================================== |
|                                                                    |
| Function:    Helper function...  Writes a Property Value pair into |
|              the given storage unit.                               |
|                                                                    |
| Algorithm:   o  Add a property and set it's value                  |
|                                                                    |
| Parameters:  storageUnit - a storage unit                          |
|              propName    - property name                           |
|              string      - value                                   |
|                                                                    |
+-------------------------------------------------------------------*/
void WriteStringProp (
	Environment*	ev, 
	ODStorageUnit*	storageUnit, 
	char*		propName, 
	char*		string)
{
	ODULong size = strlen (string) + 1;

	storageUnit->AddProperty (ev, propName)-> AddValue (ev, kJavaByteValue);

	StorageUnitSetValue (storageUnit, ev, sizeof (ODULong), &size);
	StorageUnitSetValue (storageUnit, ev, size, string);
}


/*-------------------------------------------------------------------+
|                         ReadStringProp ()                          |
| ================================================================== |
|                                                                    |
| Function:    Helper function...  Reads a Property Value pair from  |
|              a given storage unit.                                 |
|                                                                    |
| Algorithm:   o  Focus in on the property value pair (if they exist)|
|                 and read the value.                                |
|                                                                    |
| Parameters:  storageUnit - a storage unit                          |
|              propName    - property name                           |
|              stringOut   - value read from storage unit            |
|                                                                    |
+-------------------------------------------------------------------*/
void ReadStringProp (
	Environment*	ev, 
	ODStorageUnit*	storageUnit, 
	char*		propName,	
	char*		stringOut)
{
	ODULong size;

	if (storageUnit->Exists(ev, propName, kJavaByteValue, 0)) {
		storageUnit->Focus (ev, propName, kODPosUndefined, 
				    kJavaByteValue, (ODValueIndex)0, 
				    kODPosFirstSib);

		StorageUnitGetValue (storageUnit, ev, sizeof (ODULong), &size);
		StorageUnitGetValue (storageUnit, ev, size, stringOut);
	}
}


/*-------------------------------------------------------------------+
|                    WriteAppletTagToStorage ()                      |
| ================================================================== |
|                                                                    |
| Function:    Externalizes an AppletTag to an OpenDoc storage unit. |
|                                                                    |
| Parameters:  storageUnit - a storage unit                          |
|              tag         - the AppletTag to externalize            |
|                                                                    |
+-------------------------------------------------------------------*/
void WriteAppletTagToStorage (
	Environment*	ev, 
	ODStorageUnit*	storageUnit, 
	AppletTag*	tag)
{
	/*
	 *  Externalize the URL, Code and Codebase...
	 */
	WriteStringProp (ev, storageUnit, "DocumentURL", tag->fUrl);
	WriteStringProp (ev, storageUnit, "Code", tag->fCode);
	WriteStringProp (ev, storageUnit, "CodeBase", tag->fCodeBase);

	/*
	 *  Externalize the Applet arguments...
	 */
	WriteLongProp (ev, storageUnit, "NumArgs", tag->fNumArgs);

	for (int i=0; i<tag->fNumArgs; i++) { 
		char propName [20];
		sprintf (propName, "Arg%d", i);

		WriteStringProp (ev, storageUnit, propName, tag->fArgs [i]);
	}

	/*
	 *  Externalize the Width and Height...
	 */
	WriteLongProp (ev, storageUnit, "Width", tag->fWidth);
	WriteLongProp (ev, storageUnit, "Height", tag->fHeight);
}


/*-------------------------------------------------------------------+
|                    ReadAppletTagFromStorage ()                     |
| ================================================================== |
|                                                                    |
| Function:    Reads an AppletTag from an OpenDoc storage unit.      |
|                                                                    |
| Parameters:  storageUnit - a storage unit                          |
|              tag         - the AppletTag to externalize            |
|                                                                    |
+-------------------------------------------------------------------*/
AppletTag* ReadAppletTagFromStorage (
	Environment*	ev, 
	ODStorageUnit*	storageUnit)
{
	if (!storageUnit->Exists(ev, "DocumentURL", kJavaByteValue, 0)) return NULL;

	char url [255], code [255], codeBase [255];
	long width, height;
	long numArgs;
	char** args;

	/*
	 *  Read the URL, Code and Codebase values from storage...
	 */
	ReadStringProp (ev, storageUnit, "DocumentURL", url);
	ReadStringProp (ev, storageUnit, "Code", code);
	ReadStringProp (ev, storageUnit, "CodeBase", codeBase);

	/*
	 *  Read the Applet arguments from storage...
	 */
	ReadLongProp (ev, storageUnit, "NumArgs", numArgs);
	args = new char* [numArgs + 1];

	for (int i=0; i<numArgs; i++) { 
		char propName [20];
		sprintf (propName, "Arg%d", i);

		args [i] = new char [255];

		ReadStringProp (ev, storageUnit, propName, args [i]);
	}
	args [i] = NULL;

	/*
	 *  Read the Width and Height values from storage...
	 */
	ReadLongProp (ev, storageUnit, "Width", width);
	ReadLongProp (ev, storageUnit, "Height", height);

	/*
	 *  Construct and return a new AppletTag containing the data read...
	 */
	return new AppletTag (url, code, codeBase, args, width, height);
}


/*-------------------------------------------------------------------+
|                     WriteBeanTagToStorage ()                       |
| ================================================================== |
|                                                                    |
| Function:    Externalizes a BeanTag to an OpenDoc storage unit.    |
|                                                                    |
| Parameters:  storageUnit - a storage unit                          |
|              tag         - the BeanTag to externalize              |
|                                                                    |
+-------------------------------------------------------------------*/
void WriteBeanTagToStorage (
	Environment*	ev, 
	ODStorageUnit*	storageUnit, 
	BeanTag*		tag)
{
	/*
	 *  Externalize the bean className...
	 */
	WriteStringProp (ev, storageUnit, "BeanClassName", tag->fClassName);

	/*
	 *  Externalize the Width and Height...
	 */
	WriteLongProp (ev, storageUnit, "Width", tag->fWidth);
	WriteLongProp (ev, storageUnit, "Height", tag->fHeight);
}


/*-------------------------------------------------------------------+
|                     ReadBeanTagFromStorage ()                      |
| ================================================================== |
|                                                                    |
| Function:    Reads a BeanTag from an OpenDoc storage unit.         |
|                                                                    |
| Parameters:  storageUnit - a storage unit                          |
|              tag         - the BeanTag to externalize              |
|                                                                    |
+-------------------------------------------------------------------*/
BeanTag* ReadBeanTagFromStorage (
	Environment*	ev, 
	ODStorageUnit*	storageUnit)
{
	if (!storageUnit->Exists(ev, "BeanClassName", kJavaByteValue, 0)) return NULL;

	char className [255];
	long width, height;

	/*
	 *  Read the bean className value from storage...
	 */
	ReadStringProp (ev, storageUnit, "BeanClassName", className);

	/*
	 *  Read the Width and Height values from storage...
	 */
	ReadLongProp (ev, storageUnit, "Width", width);
	ReadLongProp (ev, storageUnit, "Height", height);

	/*
	 *  Construct and return a new AppletTag containing the data read...
	 */
	return new BeanTag (className, width, height);
}


/*-------------------------------------------------------------------+
|                        SOM Meta Class Methods                      |
+-------------------------------------------------------------------*/


SOMEXTERN void SOMLINK SOMInitModule (long majorVersion, long minorVersion,
	string className)
{
	SOM_IgnoreWarning (majorVersion);  /* This function makes   */
	SOM_IgnoreWarning (minorVersion);  /* no use of the passed  */
	SOM_IgnoreWarning (className);     /* arguments.            */

	JavaPartNewClass ( JavaPart_MajorVersion, JavaPart_MinorVersion);
}

int CALLBACK LibMain (HINSTANCE inst, WORD ds, WORD Heapsize, LPSTR cmdLine)
{
	SOM_ClassLibrary (JavaPartDllName);

	return 1;
}

SOM_Scope ISOString  SOMLINK M_JavaPartclsGetODPartHandlerName(
	M_JavaPart *somSelf, Environment *ev)
{
	M_JavaPartMethodDebug("M_JavaPart","M_JavaPartclsGetODPartHandlerName");

	string handlerName = (string) SOMMalloc (strlen (kJavaPartHandlerName)+1);
	strcpy (handlerName, kJavaPartHandlerName);

	return (ISOString) handlerName;
}


SOM_Scope string  SOMLINK M_JavaPartclsGetODPartHandlerDisplayName(
	M_JavaPart *somSelf, Environment *ev)
{
	M_JavaPartMethodDebug("M_JavaPart","M_JavaPartclsGetODPartHandlerDisplayName");

	string displayName = (string) SOMMalloc (strlen (kJavaPartKindDisplayName)+1);
	strcpy (displayName, kJavaPartKindDisplayName);

	return (ISOString) displayName;
}

SOM_Scope _IDL_SEQUENCE_PartKindInfo  SOMLINK M_JavaPartclsGetODPartKinds(
		M_JavaPart *somSelf, Environment *ev)
{
	M_JavaPartMethodDebug("M_JavaPart","M_JavaPartclsGetODPartKinds");

	_IDL_SEQUENCE_PartKindInfo JavaPartInfo;

	// Create structure PartKindInfo and allocate memory for variable
	PartKindInfo * info = (PartKindInfo *)SOMMalloc (sizeof (PartKindInfo));
	info->partKindName = (ISOString) SOMMalloc (strlen (kJavaPartKind) + 1);
	info->partKindDisplayName = (string)SOMMalloc (
		strlen (kJavaPartKindDisplayName)+1);
	info->filenameFilters =  (string)SOMMalloc (strlen ("")+1);
	info->filenameTypes =  (string)SOMMalloc (strlen ("")+1);
	info->categories =  (string)SOMMalloc (strlen (kJavaPartCategory) + 1);
	info->categoryDisplayName =  (string)SOMMalloc (strlen ("Sample") + 1);
	info->objectID =  (string)SOMMalloc (strlen("") + 1);

	// Copy the information into the structure
	strcpy (info->partKindName, kJavaPartKind);
	strcpy (info->partKindDisplayName, kJavaPartKindDisplayName);
	strcpy (info->filenameFilters, "");
	strcpy (info->filenameTypes, "");
	strcpy (info->categories, kJavaPartCategory);
	strcpy (info->categoryDisplayName, "Sample");
	strcpy (info->objectID, "");

	JavaPartInfo._maximum = 1;
	JavaPartInfo._length = 1;
	JavaPartInfo._buffer = info;

	return JavaPartInfo;
}

SOM_Scope string  SOMLINK M_JavaPartclsGetOLE2ClassId(
	M_JavaPart *somSelf, Environment *ev)
{
	M_JavaPartMethodDebug("M_JavaPart","M_JavaPartclsGetOLE2ClassId");

	string CLSID = "{615a1be0-0a4f-11d0-971e-0004ac77f242}";

	string classID = (string) SOMMalloc (strlen (CLSID)+1);
	strcpy (classID, CLSID);

	return (ISOString) classID;
}

SOM_Scope string  SOMLINK M_JavaPartclsGetWindowsIconFileName (
		M_JavaPart *somSelf,Environment *ev)
{
	M_JavaPartMethodDebug("M_JavaPart","M_JavaPartclsGetWindowsIconFileName");

	string icon = "iodjava.ico";

	string iconFilename = (string) SOMMalloc (strlen (icon)+1);
	strcpy (iconFilename, icon);

	return (ISOString) iconFilename;
}
