package org.eclipse.swt.ole.win32;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved
 */
import java.io.*;
import org.eclipse.swt.*;
import org.eclipse.swt.internal.ole.win32.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.internal.win32.*;

/**
 * OleControlSite provides a site to manage an embedded ActiveX Control within a container.
 *
 * <p>In addition to the behaviour provided by OleClientSite, this object provides the following: 
 * <ul>
 *	<li>events from the ActiveX control 
 * 	<li>notification of property changes from the ActiveX control
 *	<li>simplified access to well known properties of the ActiveX Control (e.g. font, background color)
 *	<li>expose ambient properties of the container to the ActiveX Control
 * </ul>
 *
 * <p>This object implements the OLE Interfaces IOleControlSite, IDispatch, and IPropertyNotifySink.
 *
 * <p>Note that although this class is a subclass of <code>Composite</code>,
 * it does not make sense to add <code>Control</code> children to it,
 * or set a layout on it.
 * </p><p>
 * <dl>
 *	<dt><b>Styles</b> <dd>BORDER 
 *	<dt><b>Events</b> <dd>Dispose, Move, Resize
 * </dl>
 *
 */
public class OleControlSite extends OleClientSite
{
	// interfaces for this container
	private COMObject iOleControlSite;
	private COMObject iDispatch;
	
	// supporting Property Change attributes
	private OlePropertyChangeSink olePropertyChangeSink;
	
	// supporting Event Sink attributes
	private OleEventSink oleEventSink;
		
	// supporting information for the Control COM object
	private CONTROLINFO currentControlInfo;
	private String licenseInfo;
	
/**
 * Create an OleControlSite child widget using style bits
 * to select a particular look or set of properties.
 *
 * @param parent a composite widget; must be an OleFrame
 * @param style the bitwise OR'ing of widget styles
 * @param progID the unique program identifier which has been registered for this ActiveX Control; 
 *               the value of the ProgID key or the value of the VersionIndependentProgID key specified
 *               in the registry for this Control (for example, the VersionIndependentProgID for 
 *               Internet Explorer is Shell.Explorer)
 *
 * @exception SWTError
 * <ul><li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
 *     <li>ERROR_ERROR_NULL_ARGUMENT when the parent is null
 *     <li>ERROR_INVALID_CLASSID when the progId does not map to a registered CLSID
 *     <li>ERROR_CANNOT_CREATE_OBJECT when failed to create OLE Object
 *     <li>ERROR_CANNOT_ACCESS_CLASSFACTORY when Class Factory could not be found
 *     <li>ERROR_CANNOT_CREATE_LICENSED_OBJECT when failed to create a licensed OLE Object
 *     <li>ERROR_INTERFACES_NOT_INITIALIZED when unable to create callbacks for OLE Interfaces</ul>
 *
 */
public OleControlSite(Composite parent, int style, String progId) {
	super(parent, style);

	createCOMInterfaces();

	// check for licensing
	appClsid = getClassID(progId);
	if (appClsid == null) OLE.error(OLE.ERROR_INVALID_CLASSID);

	int licinfo = getLicenseInfo(appClsid);
	if (licinfo == 0) {
		
		// Open a storage object
		tempStorage = createTempStorage();

		// Create ole object with storage object
		int[] address = new int[1];
		int result = COM.OleCreate(appClsid, COM.IIDIUnknown, COM.OLERENDER_DRAW, null, 0, tempStorage.getAddress(), address);
		if (result != COM.S_OK)
			OLE.error(OLE.ERROR_CANNOT_CREATE_OBJECT, result);

		objIUnknown = new IUnknown(address[0]);
		
	} else {
		// Prepare the ClassFactory
		int[] ppvObject = new int[1];
		try {
			int result = COM.CoGetClassObject(appClsid, COM.CLSCTX_INPROC_HANDLER | COM.CLSCTX_INPROC_SERVER, 0, COM.IIDIClassFactory2, ppvObject);
			if (result != COM.S_OK) {
				OLE.error(OLE.ERROR_CANNOT_ACCESS_CLASSFACTORY, result);
			}
			IClassFactory2 classFactory = new IClassFactory2(ppvObject[0]);
			// Create Com Object
			ppvObject = new int[1];
			result = classFactory.CreateInstanceLic(0, 0, COM.IIDIUnknown, licinfo, ppvObject);
			classFactory.Release();
			if (result != COM.S_OK)
				OLE.error(OLE.ERROR_CANNOT_CREATE_LICENSED_OBJECT, result);
		} finally {
			COM.SysFreeString(licinfo);
		}
		
		objIUnknown = new IUnknown(ppvObject[0]);

		// Prepare a storage medium
		ppvObject = new int[1];
		if (objIUnknown.QueryInterface(COM.IIDIPersistStorage, ppvObject) == COM.S_OK) {
			IPersistStorage persist = new IPersistStorage(ppvObject[0]);
			tempStorage = createTempStorage();
			persist.InitNew(tempStorage.getAddress());
			persist.Release();
		}
	}

	// Init sinks
	try {
		addObjectReferences();
	} catch (SWTError e) {
		disposeCOMInterfaces();
		frame.Release();
		throw e;
	}
			
	COM.OleRun(objIUnknown.getAddress());
}
/**	 
 * Adds the listener to receive events.
 *
 * @param eventID the id of the event
 * @param listener the listener
 *
 * @exception SWTError 
 *	<ul><li>ERROR_NULL_ARGUMENT when listener is null</li></ul>
 */
public void addEventListener(int eventID, OleListener listener) {
	if (listener == null) OLE.error (SWT.ERROR_NULL_ARGUMENT);
	oleEventSink.addListener(eventID, listener);
}
protected void addObjectReferences() {

	super.addObjectReferences();
	
	// Get event notification from control
	connectEventSink();
	// Get property change notification from control
	connectPropertyChangeSink();

	// Get access to the Control object
	int[] ppvObject = new int[1];
	if (objIUnknown.QueryInterface(COM.IIDIOleControl, ppvObject) == COM.S_OK) {
		IOleControl objIOleControl = new IOleControl(ppvObject[0]);
		// ask the control for its info in case users
		// need to act on it
		currentControlInfo = new CONTROLINFO();
		objIOleControl.GetControlInfo(currentControlInfo);
		objIOleControl.Release();
	}		
}
/**	 
 * Adds the listener to receive events.
 *
 * @param propertyID the identifier of the property
 * @param listener the listener
 *
 * @exception SWTError 
 *	<ul><li>ERROR_NULL_ARGUMENT when listener is null</li></ul>
 */
public void addPropertyListener(int propertyID, OleListener listener) {
	if (listener == null) throw new SWTError (SWT.ERROR_NULL_ARGUMENT);
	olePropertyChangeSink.addListener(propertyID, listener);	
}
private void connectEventSink() {
	oleEventSink = new OleEventSink(this);
	oleEventSink.AddRef();
	oleEventSink.connect(objIUnknown);
}
private void connectPropertyChangeSink() {
	olePropertyChangeSink = new OlePropertyChangeSink(this);
	olePropertyChangeSink.AddRef();
	olePropertyChangeSink.connect(objIUnknown);
}
protected void createCOMInterfaces () {
	super.createCOMInterfaces();
	
	// register each of the interfaces that this object implements
	iOleControlSite = new COMObject(new int[]{2, 0, 0, 0, 1, 1, 3, 2, 1, 0}){
		public int method0(int[] args) {return QueryInterface(args[0], args[1]);}
		public int method1(int[] args) {return AddRef();}
		public int method2(int[] args) {return Release();}
		public int method3(int[] args) {return OnControlInfoChanged();}
		// method4 LockInPlaceActive - not implemented
		// method5 GetExtendedControl - not implemented
		// method6 TransformCoords - not implemented
		// method7 Translate Accelerator - not implemented
		public int method8(int[] args) {return OnFocus(args[0]);}
		// method9 ShowPropertyFrame - not implemented
	};
	
	iDispatch = new COMObject(new int[]{2, 0, 0, 1, 3, 5, 8}){
		public int method0(int[] args) {return QueryInterface(args[0], args[1]);}
		public int method1(int[] args) {return AddRef();}
		public int method2(int[] args) {return Release();}
		// method3 GetTypeInfoCount - not implemented
		// method4 GetTypeInfo - not implemented
		// method5 GetIDsOfNames - not implemented
		public int method6(int[] args) {return Invoke(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);}
	};
}
private void disconnectEventSink() {

	if (oleEventSink != null) {
		oleEventSink.disconnect(objIUnknown);
		oleEventSink.Release();
	}
	oleEventSink = null;
}
private void disconnectPropertyChangeSink() {

	if (olePropertyChangeSink != null) {
		olePropertyChangeSink.disconnect(objIUnknown);
		olePropertyChangeSink.Release();
	}
	olePropertyChangeSink = null;
}
protected void disposeCOMInterfaces() {
	super.disposeCOMInterfaces();

	if (iOleControlSite != null)
		iOleControlSite.dispose();
	iOleControlSite = null;

	if (iDispatch != null)
		iDispatch.dispose();
	iDispatch = null;
}
public Color getBackground () {

	if (objIUnknown != null) {
		// !! We are getting the OLE_COLOR - should we change this to the COLORREF value?
		OleAutomation oleObject= new OleAutomation(this);
		Variant varBackColor = oleObject.getProperty(COM.DISPID_BACKCOLOR);
		oleObject.dispose();
	
		if (varBackColor != null){
			int[] colorRef = new int[1];
			if (COM.OleTranslateColor(varBackColor.getInt(), getDisplay().hPalette, colorRef) == COM.S_OK)
				return Color.win32_new(getDisplay(), colorRef[0]);
		}
	}
		
	return super.getBackground();
}
public Font getFont () {

	if (objIUnknown != null) {
		OleAutomation oleObject= new OleAutomation(this);
		Variant varDispFont = oleObject.getProperty(COM.DISPID_FONT);
		oleObject.dispose();
	
		if (varDispFont != null){
			OleAutomation iDispFont = varDispFont.getAutomation();
			Variant lfFaceName = iDispFont.getProperty(COM.DISPID_FONT_NAME);
			Variant lfHeight   = iDispFont.getProperty(COM.DISPID_FONT_SIZE);
			Variant lfItalic   = iDispFont.getProperty(COM.DISPID_FONT_ITALIC);
			//Variant lfCharSet  = iDispFont.getProperty(COM.DISPID_FONT_CHARSET);
			Variant lfBold     = iDispFont.getProperty(COM.DISPID_FONT_BOLD);
			iDispFont.dispose();

			if (lfFaceName != null && 
				lfHeight != null && 
				lfItalic != null && 
				lfBold != null){
				int style = 3 * lfBold.getInt() + 2 * lfItalic.getInt();
				Font font = new Font(getShell().getDisplay(), lfFaceName.getString(), lfHeight.getInt(), style);
				return font;
			}
		}
	}
		
	return super.getFont();
}
public Color getForeground () {

	if (objIUnknown != null) {
		// !! We are getting the OLE_COLOR - should we change this to the COLORREF value?
		OleAutomation oleObject= new OleAutomation(this);
		Variant varForeColor = oleObject.getProperty(COM.DISPID_FORECOLOR);
		oleObject.dispose();
	
		if (varForeColor != null){
			int[] colorRef = new int[1];
			if (COM.OleTranslateColor(varForeColor.getInt(), getDisplay().hPalette, colorRef) == COM.S_OK)
				return Color.win32_new(getDisplay(), colorRef[0]);
		}
	}
		
	return super.getForeground();
}
protected int getLicenseInfo(GUID clsid) {
	int[] ppvObject = new int[1];

	if (COM.CoGetClassObject(clsid, COM.CLSCTX_INPROC_HANDLER | COM.CLSCTX_INPROC_SERVER, 0, COM.IIDIClassFactory2, ppvObject) != COM.S_OK) {
		return 0;
	}
	IClassFactory2 classFactory = new IClassFactory2(ppvObject[0]);
	LICINFO licinfo = new LICINFO();
	if (classFactory.GetLicInfo(licinfo) != COM.S_OK) {
		classFactory.Release();
		return 0;
	}
	int[] pBstrKey = new int[1];
	if (licinfo != null && licinfo.fRuntimeKeyAvail != 0) {
		if (classFactory.RequestLicKey(0, pBstrKey) == COM.S_OK) {
			classFactory.Release();
			return pBstrKey[0];
		}
	}
	classFactory.Release();
	return 0;
}
protected int GetWindow(int phwnd) {

	if (phwnd == 0)
		return COM.E_INVALIDARG;
	if (frame == null) {
		COM.MoveMemory(phwnd, new int[] {0}, 4);
		return COM.E_NOTIMPL;
	}
	
	// Copy the Window's handle into the memory passed in
	COM.MoveMemory(phwnd, new int[] {handle}, 4);
	return COM.S_OK;
}
private int Invoke(int dispIdMember, int riid, int lcid, int dwFlags, int pDispParams, int pVarResult, int pExcepInfo, int pArgErr) {
	if (pVarResult == 0 || dwFlags != COM.DISPATCH_PROPERTYGET) {
		if (pExcepInfo != 0) COM.MoveMemory(pExcepInfo, new int[] {0}, 4);
		if (pArgErr != 0) COM.MoveMemory(pArgErr, new int[] {0}, 4);
		return COM.DISP_E_MEMBERNOTFOUND;
	}
	switch (dispIdMember) {
		case COM.DISPID_AMBIENT_USERMODE :
			Variant usermode = new Variant(true);
			if (pVarResult != 0) usermode.getData(pVarResult);
			return COM.S_OK;
			
		case COM.DISPID_AMBIENT_UIDEAD :
			Variant uidead = new Variant(false);
			if (pVarResult != 0) uidead.getData(pVarResult);
			return COM.S_OK;

			// indicate a false result
		case COM.DISPID_AMBIENT_SUPPORTSMNEMONICS :
		case COM.DISPID_AMBIENT_SHOWGRABHANDLES :
		case COM.DISPID_AMBIENT_SHOWHATCHING :
			if (pVarResult != 0) COM.MoveMemory(pVarResult, new int[] {0}, 4);
			if (pExcepInfo != 0) COM.MoveMemory(pExcepInfo, new int[] {0}, 4);
			if (pArgErr != 0) COM.MoveMemory(pArgErr, new int[] {0}, 4);
			return COM.S_FALSE;

			// not implemented
		case COM.DISPID_AMBIENT_OFFLINEIFNOTCONNECTED :
		case COM.DISPID_AMBIENT_BACKCOLOR :
		case COM.DISPID_AMBIENT_FORECOLOR :
		case COM.DISPID_AMBIENT_FONT :
		case COM.DISPID_AMBIENT_LOCALEID :
		case COM.DISPID_AMBIENT_SILENT :
		case COM.DISPID_AMBIENT_MESSAGEREFLECT :
			if (pVarResult != 0) COM.MoveMemory(pVarResult, new int[] {0}, 4);
			if (pExcepInfo != 0) COM.MoveMemory(pExcepInfo, new int[] {0}, 4);
			if (pArgErr != 0) COM.MoveMemory(pArgErr, new int[] {0}, 4);
			return COM.E_NOTIMPL;
			
		default :
			if (pVarResult != 0) COM.MoveMemory(pVarResult, new int[] {0}, 4);
			if (pExcepInfo != 0) COM.MoveMemory(pExcepInfo, new int[] {0}, 4);
			if (pArgErr != 0) COM.MoveMemory(pArgErr, new int[] {0}, 4);
			return COM.DISP_E_MEMBERNOTFOUND;
	}
}
private int OnControlInfoChanged() {
	int[] ppvObject = new int[1];
	if (objIUnknown.QueryInterface(COM.IIDIOleControl, ppvObject) == COM.S_OK) {
		IOleControl objIOleControl = new IOleControl(ppvObject[0]);
		// ask the control for its info in case users
		// need to act on it
		currentControlInfo = new CONTROLINFO();
		objIOleControl.GetControlInfo(currentControlInfo);
		objIOleControl.Release();
	}
	return COM.S_OK;
}
private int OnFocus(int fGotFocus) {
	return COM.S_OK;
}
protected int OnUIDeactivate(int fUndoable) {
	// controls don't need to do anything for
	// border space or menubars
	return COM.S_OK;
}
protected int QueryInterface(int riid, int ppvObject) {
	int result = super.QueryInterface(riid, ppvObject);
	if (result == COM.S_OK)
		return result;
	if (riid == 0 || ppvObject == 0)
		return COM.E_INVALIDARG;
	GUID guid = new GUID();
	COM.MoveMemory(guid, riid, GUID.sizeof);
	if (COM.IsEqualGUID(guid, COM.IIDIOleControlSite)) {
		COM.MoveMemory(ppvObject, new int[] {iOleControlSite.getAddress()}, 4);
		AddRef();
		return COM.S_OK;
	}
	if (COM.IsEqualGUID(guid, COM.IIDIDispatch)) {
		COM.MoveMemory(ppvObject, new int[] {iDispatch.getAddress()}, 4);
		AddRef();
		return COM.S_OK;
	}
	COM.MoveMemory(ppvObject, new int[] {0}, 4);
	return COM.E_NOINTERFACE;
}
protected void releaseObjectInterfaces() {
	
	disconnectEventSink();
	
	disconnectPropertyChangeSink();

	super.releaseObjectInterfaces();
}
/**	 
 * Removes the listener.
 *
 * @param listener the listener
 *
 * @exception SWTError
 *	<ul><li>ERROR_NULL_ARGUMENT when listener is null</li></ul>
 */
public void removeEventListener(int eventID, OleListener listener) {
	if (listener == null) throw new SWTError (SWT.ERROR_NULL_ARGUMENT);
	oleEventSink.removeListener(eventID, listener);
}
/**	 
 * Removes the listener.
 *
 * @param listener the listener
 *
 * @exception SWTError
 *	<ul><li>ERROR_NULL_ARGUMENT when listener is null</li></ul>
 */
public void removePropertyListener(int propertyID, OleListener listener) {
	if (listener == null) throw new SWTError (SWT.ERROR_NULL_ARGUMENT);
	olePropertyChangeSink.removeListener(propertyID, listener);
}
public void setBackground (Color color) {

	super.setBackground(color);

	//set the background of the ActiveX Control
	if (objIUnknown != null) {
		OleAutomation oleObject= new OleAutomation(this);
		oleObject.setProperty(COM.DISPID_BACKCOLOR, new Variant(color.handle));
		oleObject.dispose();
	}
}
public void setFont (Font font) {

	super.setFont(font);
	
	//set the font of the ActiveX Control
	if (objIUnknown != null) {
		
		OleAutomation oleObject= new OleAutomation(this);
		Variant varDispFont = oleObject.getProperty(COM.DISPID_FONT);
		oleObject.dispose();
	
		if (varDispFont != null){
			OleAutomation iDispFont = varDispFont.getAutomation();
			FontData[] fdata = font.getFontData();
			iDispFont.setProperty(COM.DISPID_FONT_NAME,   new Variant(fdata[0].getName()));
			iDispFont.setProperty(COM.DISPID_FONT_SIZE,   new Variant(fdata[0].getHeight()));
			iDispFont.setProperty(COM.DISPID_FONT_ITALIC, new Variant(fdata[0].getStyle() & SWT.ITALIC));
			//iDispFont.setProperty(COM.DISPID_FONT_CHARSET, new Variant(fdata[0].getCharset));
			iDispFont.setProperty(COM.DISPID_FONT_BOLD,   new Variant((fdata[0].getStyle() & SWT.BOLD)));
			iDispFont.dispose();
		}
	}
		
	return;
}
public void setForeground (Color color) {

	super.setForeground(color);

	//set the foreground of the ActiveX Control
	if (objIUnknown != null) {
		OleAutomation oleObject= new OleAutomation(this);
		oleObject.setProperty(COM.DISPID_FORECOLOR, new Variant(color.handle));
		oleObject.dispose();
	}
}
}
