/**
 * This file describes the port used to draw objects in 2D graphics.
 * Classes described here are:
 *		IGrafPort, IBaseRootGrafPort, ILinkedGrafPort, and IStatefulGrafPort.
 *
 *   IBM Open Class Library
 *   (C) Copyright International Business Machines Corporation,  1997
 *   Licensed Material - Program-Property of IBM - All Rights Reserved.
 *
 */

// Revision: 91 1.38.1.16 source/albert/graph2d/igrport.hpp, 2d, ioc.v400, 001006 

#ifndef _IGRPORT_
#define _IGRPORT_

#include <imatrix.hpp>
#include <i2dghand.hpp>
#include <istring.hpp>
#include <icoordsy.hpp>
#include <icolmap.hpp>

#if __IBMCPP__ >= 400
#pragma namemangling(compat)
#endif

class IRectangle;
class IGArea;
class IGCurve2D;
class IGEllipse2D;
class IGLine2D;
class IGPoint2D;
class IGPolygon2D;
class IGLoop2D;
class IGPolyline2D;
class IGRect2D;
class IGImage;
class IGTextRun;
class IAttributeState;
class IGrafBundle;

class IGrafState;
class IRootGrafState;
class ILinkedGrafState;
class IStatefulGrafState;
class IGrafDevice;
class IGrafStateOrphanage;

#ifdef IC_MOTIF
	struct _XDisplay;
	struct _XGC;
#endif

#pragma pack(push,4)
#pragma enum(4)

/**
 * IGrafPort is an abstract class that represents a port, one of the central objects of the Graphics system.
 * IGrafPort is an abstract class that represents a port, one of the central objects of the Graphics system.
 * Graphics are drawn to a port, which in turn invokes the rendering operations of a particular device.
 * Object of this class cannot be copied or copy-contructed.
*/

class IGrafPort {
public:
  enum EGrafPortType { kIBaseRootGrafPort, kIExtendedRootGrafPort };

	virtual ~IGrafPort();

	// draw calls (non-virtual because they just call the device; not to be overridden).
	// These functions are provided as a convenience; they simply call the corresponding
	// IGrafDevice::RenderXXX function, passing the geometry, graphic state, and device
	// cache.
	
	/**
	 * Renders the given geometry IGLine2D on the graphics device specified by this IGrafPort object.
	 */
	void draw(const IGLine2D& geometry);

	/**
	 * Renders the given geometry IGPolyline2D on the graphics device specified by this IGrafPort object.
	 */
	void draw(const IGPolyline2D& geometry);

	/**
     * Renders the given geometry IGCurve2D on the graphics device specified by this IGrafPort object.
     */
	void draw(const IGCurve2D& geometry);

    /**
     * Renders the given geometry IGRect2D on the graphics device specified by this IGrafPort object.
     */
    void draw(const IGRect2D& geometry);

    /**
     * Renders the given geometry IGEllipse2D on the graphics device specified by this IGrafPort object.
     */
    void draw(const IGEllipse2D& geometry);

    /**
     * Renders the given geometry IGPolygon2D on the graphics device specified by this IGrafPort object.
     */
    void draw(const IGPolygon2D& geometry);

    /**
     * Renders the given geometry IGLoop2D on the graphics device specified by this IGrafPort object.
     */
    void draw(const IGLoop2D& geometry);

    /**
     * Renders the given geometry IGArea on the graphics device specified by this IGrafPort object.
     */
    void draw(const IGArea& geometry);

    /**
     * Renders the given geometry IGImage on the graphics device.
     */
	void draw(const IGImage& geometry);

    /**
     * Renders the given geometry IGImage on the graphics device using a mask.
     */
	void draw(const IGImage& geometry, const IGImage& theMask);

    /**
     * Renders the given geometry IGImage on the graphics device using a specified bounding rectangle.
     */
    void draw(const IGImage& theImage, const IGRect2D& srcBounds);

    /**
     * Renders the given geometry IGImage on the graphics device using using a specified bounding rectangle and a mask.
     */
    void draw(const IGImage& theImage, const IGImage& theMask, const IGRect2D& srcBounds);

	// draw calls with overriding attribute state and model matrix.
	// These functions are identical to the functions above except for the attribute
	// state and model matrix, which are concatenated with the attribute state and model
	// matrix of the grafport for the duration of the call.  The concatenated result is
	// passed to the device.  Use of these calls is not recommended if more than one
	// call is made using the same attribute state or matrix because the concatenation
	// takes place each time the call is made.  For greater efficiency, use linked
	// grafports instead.

    /**
     * Renders the given geometry IGLine2D on the graphics device specified by this IGrafPort object.
     */
    void draw(
		const IGLine2D& geometry,
		const IAttributeState& attributeState,
		const IGrafMatrix& modelMatrix = IGrafMatrix::identity());

    /**
     * Renders the given geometry IGPolyline2D on the graphics device specified by this IGrafPort object.
     */
    void draw(
		const IGPolyline2D& geometry,
		const IAttributeState& attributeState,
		const IGrafMatrix& modelMatrix = IGrafMatrix::identity());

    /**
     * Renders the given geometry IGCurve2D on the graphics device specified by this IGrafPort object.
     */
    void draw(
		const IGCurve2D& geometry,
		const IAttributeState& attributeState,
		const IGrafMatrix& modelMatrix = IGrafMatrix::identity());

    /**
     * Renders the given geometry IGRect2D on the graphics device specified by this IGrafPort object.
     */
    void draw(
		const IGRect2D& geometry,
		const IAttributeState& attributeState,
		const IGrafMatrix& modelMatrix = IGrafMatrix::identity());

    /**
     * Renders the given geometry IGEllipse2D on the graphics device specified by this IGrafPort object.
     */
    void draw(
		const IGEllipse2D& geometry,
		const IAttributeState& attributeState,
		const IGrafMatrix& modelMatrix = IGrafMatrix::identity());

    /**
     * Renders the given geometry IGPolygon2D on the graphics device specified by this IGrafPort object.
     */
    void draw(
		const IGPolygon2D& geometry,
		const IAttributeState& attributeState,
		const IGrafMatrix& modelMatrix = IGrafMatrix::identity());

    /**
     * Renders the given geometry IGLoop2D on the graphics device specified by this IGrafPort object.
     */
    void draw(
		const IGLoop2D& geometry,
		const IAttributeState& attributeState,
		const IGrafMatrix& modelMatrix = IGrafMatrix::identity());

    /**
     * Renders the given geometry IGArea on the graphics device specified by this IGrafPort object.
     */
    void draw(
		const IGArea& geometry,
		const IAttributeState& attributeState,
		const IGrafMatrix& modelMatrix = IGrafMatrix::identity());
	
    /**
     * Renders the given geometry IGImage on the graphics device with overriding states.
     */
	void draw(
		const IGImage& geometry,
		const IAttributeState& attributeState,
		const IGrafMatrix& modelMatrix = IGrafMatrix::identity());

    /**
     * Renders the given geometry IGImage on the graphics device with overriding states.
     */
	void draw (
		const IGImage& theImage,
		const IGImage& theMask,
		const IAttributeState& attributeState,
		const IGrafMatrix& modelMatrix = IGrafMatrix::identity());

    /**
     * Renders partial image by transfering pixels within a rectangular area.
     */
    void draw(
		const IGImage& theImage,
		const IGRect2D& srcBounds,
		const IAttributeState& attributeState,
		const IGrafMatrix& modelMatrix = IGrafMatrix::identity());

    /**
     * Renders a partial transparent (masked) image by transfering pixels within a rectangular area.
     */
    void draw(
		const IGImage& theImage,
		const IGImage& theMask,
		const IGRect2D& srcBounds,
		const IAttributeState& attributeState,
		const IGrafMatrix& modelMatrix = IGrafMatrix::identity());

    /**
     * Gets the IGrafMatrix of this IGrafPort based on the specified matrix kind.
     */
	const IGrafMatrix* matrix(EMatrixKind) const;

    /**
     * Gets the clipping area of of the IGrafState.
     */
	const IGArea* clipArea() const;
									
    /**
     * Gets the attribute states of the IGrafState.
     */
	const IAttributeState* attributes() const;

    /**
     * Relinquishes knowledge of, and responsibility for, the device context, returning it to the caller.
     */
	IPresSpaceHandle orphanDeviceContext();

    /**
     * Takes over the ownership of a device context without deleting any existing device context.
     * Takes over the ownership of a device context without deleting any existing device context.
     * The device context is orphaned when this IGrafPort is destroyed.
     */
    void adoptDeviceContext(IPresSpaceHandle);
	
    /**
     * Device tranformation being inverted back to logical coordinate system.
     */
	virtual const IGrafMatrix& invertedDeviceTransform() const;
	
  /**
     * Transforamtion from pixel unit which is device dependent to point size unit which is device independent.
     */
	virtual  const IGrafMatrix&  pixelToPointSize() const;

    /**
     * Gets the device type encapsulated by this IGrafPort.
     */	
	const IString* portType() const;

    /**
     * Marks the graphic state as being in use so that no changes to the state are made until IGrafPort::doneWithState is called.
     */
    virtual void useState() const = 0;

    /**
     * Marks the graphic state as being no longer in use so that changes to the state can be made.
     */
    virtual void doneWithState() const = 0;

    /**
     * Provides a more efficient way to get access to the port that needs to have its usage registered.
     */
    virtual const IGrafPort* portForStateUsage() const;	
		
		/**
		  * Convert an IRectangle which is in native coordinate into IGRect2D which is in ICoordinateSystem
			*/
		virtual  IGRect2D convertRect(const IRectangle) const;

	virtual const IPresSpaceHandle& deviceContext();

	virtual void flush();

#ifdef IC_MOTIF
    /**
	 *access funtions for exposing IXDC's display, drawable and gc
     */
	virtual _XDisplay* display() const;
	virtual unsigned long drawable() const;
	virtual _XGC* gc() const;
    static bool restoreGC;
#endif //IC_MOTIF

protected:
    /**
     * Protect default constructor.
     */
	IGrafPort();

    /**
     * Constructs an IGrafPort from a graf device.
     */
	IGrafPort(IGrafDevice* referencedDevice, IColorMap *colormap=&(IColorMap::defaultColorMap()));

public:
	// Used only by the implementation of IDrawableText.  IGTextRun in non-API.
	// returns the nextLocation position...
	IGPoint2D draw(const IGTextRun& geometry);

	IGPoint2D draw(
		const IGTextRun& geometry,
		const IAttributeState& attributeState,
		const IGrafMatrix& modelMatrix = IGrafMatrix::identity());

protected:
friend class IPaintEvent; // IPaintEvent::setGrafPort
friend class IIconHandler; // IIconHandler::paintWindow
friend class IGraphicText; // IGraphicText::looseFitBounds
friend class IBaseRootGrafPort;
friend class ILinkedGrafPort;
friend class IStatefulGrafPort;
friend class IGTextRun;
friend class IGraph2DTestHelper;
friend class IOLEEmbeddedComponentViewImp;
friend class IBidiSettings;
friend class IGBidiSettings;
friend class IRootGrafPort;

	// Device access calls
	IGrafDevice* device();
	void setDevice(IGrafDevice* device);

	const IGrafState* state() const;
	void setState(IGrafState* state);

	void adoptOrphanedGrafState(IGrafState* orphan);

private:
	// None of the following objects are owned; all are referenced (alias)
	IGrafDevice* fDevice;
#if IC_RTTI_ENABLED
	IString fDeviceType;
#endif // IC_RTTI_ENABLED
	IGrafState* fGrafState;
	IColorMapContext* fColormapContext;

	IGrafStateOrphanage* fGrafStateOrphanage;

	// disabled:
	IGrafPort(const IGrafPort&);
	IGrafPort& operator=(const IGrafPort& source);
};

class IPresSpaceHandle;	

/**
 * An IBaseRootGrafPort represents the top port of a port hierarchy.
 * An IBaseRootGrafPort represents the top port of a port hierarchy.
 * IBaseRootGrafPort uses "ideal" coordinate  which is in point size (1/72 inch) to draw graphics.
 * Object of this class cannot be copied or copy-contructed.
*/
class IBaseRootGrafPort : public IGrafPort {
public:
	virtual ~IBaseRootGrafPort();

    /**
     * Marks the graphic state as being in use so that no changes to the state are made until doneWithState is called.
     */
    virtual void useState() const;

    /**
     * Marks the graphic state as being no longer in use so that changes to the state can be made.
     */
    virtual void doneWithState() const;

    /**
     * Device tranformation being inverted back to logical coordinate system.
     */
    virtual const IGrafMatrix& invertedDeviceTransform() const;

  /**
     * Converts from device coordinate which is in pixel to "ideal" coordinate which is in point size ( 1/72 inch).
     */
	virtual  const IGrafMatrix&  pixelToPointSize() const;
	
    /**
     * Returns the bounding rectangle of the IGrafDevice in world coordinates.
     */
	IGRect2D worldBounds() const;

    /**
     * Constructs an IBaseRootGrafPort by adopting an IPresSpaceHandle.
     */
    IBaseRootGrafPort(const IPresSpaceHandle& deviceContextToBeAdopted,
			IColorMap *colormap=&(IColorMap::defaultColorMap()));

#ifdef IC_MOTIF
    /**
	 *access funtions for exposing IXDC's display, drawable and gc
     */
	virtual _XDisplay* display() const;
	virtual unsigned long drawable() const;
	virtual _XGC* gc() const;
#endif //IC_MOTIF
		
protected:
    /**
     * Sets up coordinate system. Default is left-hand coordinate system.
     */
	void setupCoordinateSystem(int coordinateSystem);

private:
friend class IExtendedRootGrafPort;
friend class IGImage;
friend class IGraph2DTestHelper;
friend class IInternalPrintChannel;
friend class IMakeMetaFile;
friend class IAswOleObject;
	IBaseRootGrafPort(IGrafDevice* referencedDevice,
				IColorMap *colormap=&(IColorMap::defaultColorMap()),
				ICoordinateSystem::EOrientation=ICoordinateSystem::kOriginUpperLeft);


private:
	IRootGrafState* fRootGrafState;

	IGrafMatrix* fInvertedDeviceMatrix;
	IGrafMatrix* fPixelToPointSizeMatrix;

	// disabled:
	IBaseRootGrafPort();
	IBaseRootGrafPort(const IBaseRootGrafPort&);
	IBaseRootGrafPort& operator=(const IBaseRootGrafPort& source);
};

/**
 * ILinkedGrafPort provides the basic functionality for linked ports.
 * ILinkedGrafPort provides the basic functionality for linked ports.
 * Object of this class cannot be copied or copy-contructed.
 */

class ILinkedGrafPort : public IGrafPort {
public:
	virtual ~ILinkedGrafPort();

    /**
     * Constructs an ILinkedGrafPort reference to the attributes.
     */
	ILinkedGrafPort(
		IGrafPort* referencedParent,
		const IAttributeState* referencedAttributes);

    /**
     * Constructs an ILinkedGrafPort reference to a transformation matrix.
     */
	ILinkedGrafPort(
		IGrafPort* referencedParent,
		EMatrixKind matrixKind,
		const IGrafMatrix* referencedMatrix);	// perspective view matrix will have unpredictable results on pen, cap and joints

    /**
     * Constructs an ILinkedGrafPort reference to clipping information.
     */
	ILinkedGrafPort(
		IGrafPort* referencedParent,
		const IGArea* referencedClipArea);

    /**
     * Marks the graphic state as being in use so that no changes to the state are made until doneWithState is called.
     */
    virtual void useState() const;

    /**
     * Marks the graphic state as being no longer in use so that changes to the state can be made.
     */
    virtual void doneWithState() const;

    /**
     * Provides a more efficient way to get access to the port that needs to have its usage registered.
     */
    virtual const IGrafPort* portForStateUsage() const;

    /**
     * Device tranformation being inverted back to logical coordinate system.
     */
    virtual const IGrafMatrix& invertedDeviceTransform() const;
		
	 /**
     * Transforamtion from pixel unit to point size unit.
     */
	virtual  const IGrafMatrix&  pixelToPointSize() const;

private:
	// This is the concatenated state of all the states from root and up...
	ILinkedGrafState* fLinkedGrafState;

	// The following object is not owned; referenced (alias)
	const IGrafPort* fPortForStateUsage;
	IGrafPort* fParent;

	// disabled:
	ILinkedGrafPort();
	ILinkedGrafPort(const ILinkedGrafPort&);
	ILinkedGrafPort& operator=(const ILinkedGrafPort& source);
};


/**
 * IStatefulGrafPort provides the ability to set the value of the substates individually.
 * IStatefulGrafPort provides the ability to set the value of the substates individually.
 * Object of this class cannot be copied or copy-contructed.
 */

class IStatefulGrafPort : public IGrafPort {
public:

    /**
     * Constructs a stateful grafport from a root grafport.
     */
	IStatefulGrafPort(IBaseRootGrafPort* root);

	virtual ~IStatefulGrafPort();

	/**
	 * Marks the graphic state as being in use so that no changes to the state are made until doneWithState is called.
	 */
	virtual void useState() const;

	/**
	 * Marks the graphic state as being no longer in use so that changes to the state can be made.
	 */
	virtual void doneWithState() const;

	/**
	 * Marks the graphic state as being no longer in use so that changes to the state can be made.
	 */
	virtual const IGrafPort* portForStateUsage() const;

    /**
     * Device tranformation being inverted back to logical coordinate system.
     */
	virtual const IGrafMatrix& invertedDeviceTransform() const;
	
	/**
     * Transforamtion from pixel unit to point size unit.
     */
	virtual  const IGrafMatrix&  pixelToPointSize() const;

 	/**
     * Relinquishes knowledge of, and responsibility for, the device context, returning it to the caller.
     */
	IPresSpaceHandle orphanDeviceContext();

    /**
     * Takes over the ownership of a device context without deleting any existing device context.
     * Takes over the ownership of a device context without deleting any existing device context.
     * The device context is orphaned when this IStatefulGrafPort is destroyed.
     */
	void adoptDeviceContext(IPresSpaceHandle);
	
	/**
	 * Sets the substate bundle.
	 */
 	void setBundle(const IGrafBundle& bundle);

	/**
	 * Sets the substate matrix.
	 */
	void setMatrix(EMatrixKind matrixKind, const IGrafMatrix& matrix);

	/**
	 * Sets the substate clipping area.
	 */
	void setClipArea(const IGArea& clipArea);

private:
	// This is the concatenated state of all the states from root and up...
	IStatefulGrafState* fStatefulGrafState;
	IGrafPort* fParent;

	IStatefulGrafPort();
	IStatefulGrafPort(const IStatefulGrafPort&);
	IStatefulGrafPort& operator=(const IStatefulGrafPort& source);
};

#pragma enum(pop)
#pragma pack(pop)

#if __IBMCPP__ >= 400
#pragma namemangling()
#endif

#if (IC_OBSOLETE <= IC_OBSOLETE_3)
#include <iexgrprt.hpp>
#endif // IC_OBSOLETE

#endif // _IGRPORT_
