/**
 * This file describes the frame attributes and transfer modes needed for rendering.
 * Classes described here are:
 *		IPen
 *		ICap
 *		IJoint
 *		IImageTransferMode
 *		IColorTransferMode
 *		IImageSamplingControl
 *
 *   IBM Open Class Library
 *   (C) Copyright International Business Machines Corporation,  1997
 *   Licensed Material - Program-Property of IBM - All Rights Reserved.
 *
 */

// Revision: 54 1.22.1.7 source/albert/graph2d/igrafatt.hpp, 2d, ioc.v400, 980918 

#ifndef _IGRAFATT_
#define _IGRAFATT_

#include <igrtypes.hpp>
#include <igbase2d.hpp>
#include <imstrmbl.hpp>
#include <iprimtyp.hpp>

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

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

/**
 *  IPen class is designed to encapsulate most of the functionality of 2D pens.
 *  Typically one would design seperate classes for some of these classes, however, the
 *  customer feed back we have received (for fewer flat classes) has helped in coming up
 *  with the class below. The encapsulation of some of the classes is not as kosher as
 *  we would have liked, but this design removes the polymorphic behavior which is generally
 *  expensive.
 */

class IPen : public IMSTREAMABLE
{
	StreamableDeclarationsMacro(IPen);

protected :
	virtual void writeToStream(IDataStream& toWhere) const;
	virtual void readFromStream(IDataStream& toWhere);

public:
	/** EPenBalance describes where a line is drawn relative to the edge of the geometry. */
    enum EPenBalance {
		kCenterFrame,         // Centered for both open and closed geometries
		kInsetFrame,		  // Inside for closed geometries
		kUnknownFrame
    };

	/** EPenType describes the details of the pen behavior. */
    enum EPenType {
		kHairline,
		kSolid,
		kDashed,
		kDot,
		kDashDot,
		kDashDotDot,
		kInvisible,
		kUnknownPen
    };

	/**
	 * When creating a kHairline Pen the penWidth and the pen Balance parameters are ignored.
	 */
	IPen();

	/**
	 * When creating a kHairline Pen the penWidth and the pen Balance parameters are ignored.
	 */
    IPen(EPenType type, GCoordinate penWidth = 1.0, EPenBalance = kCenterFrame );

	/**
	 * Copy constructor.
	 */
    IPen(const IPen&);

    ~IPen();

	/**
	 * Sets the parameters of this pen using suitable combinations.
	 * Sets the parameters of this pen using suitable combinations.
	 * (e.g. for kHairline sets penWidth to 1.0 and penBalance to unknownFrame)
	 * The Pen Balance attribute of the pen does not affect the rendering of open geometries
	 * such as lines, curves etc. Also, for hairline pen the pen width and the penBalance
	 * attributes are ignored.
	 */
    void setPenParams(EPenType type,GCoordinate penWidth = 1.0, EPenBalance = kCenterFrame);

	/**
	 * Sets the width of the pen in world coordinates using suitable combinations.
	 */
    void setPenWidth(GCoordinate penWidth);

	/**
	 * Sets the type of pen balance using suitable combinations.
	 * Sets the type of pen balance using suitable combinations.
   * (e.g. for kHairline sets penWidth to 1.0 and penBalance to unknownFrame)
	 */
    void setPenBalance(EPenBalance penBalance);

	/**
	 * Sets the type of the pen using suitable combinations.
	 * Sets the type of the pen using suitable combinations.(e.g. for kHairline sets penWidth to 1.0 and penBalance to unknownFrame)
	 * For pens setting of the pen type might also reset the other paramters:
	 * 	for kHairline, sets PenWidth to 1.0 and PenBalance to unknownFrame;
	 *	for kUnknownPen, sets PenWidth to 1.0 and PenBalance to UnknownFrame;
	 *	otherwise, no change.
	 */
    void setPenType(EPenType penType);

	/**
	 * Gets the parameters of this pen.
	 */
    EPenType penParams(GCoordinate& penWidth, EPenBalance& penBalance) const;

	/**
	 * Gets the type of this pen.
	 */
    EPenType penType() const;

	/**
	 * Gets the type of pen balance.
	 */
    EPenBalance penBalance() const;

	/**
	 * Gets the width of the pen in world coordinates.
	 */
    GCoordinate penWidth() const;

	/**
	 * Assignment operator.
	 */
    IPen& operator=(const IPen& source);

	/**
	 * Tests two IPen objects for equality.
	 */
    virtual bool operator==(const IPen&) const;

	/**
	 * Tests two IPen objects for inequality.
	 */
    virtual bool operator!=(const IPen&) const;

private:
friend class IMGraphic;
	IGRect2D adjustBounds(const IGRect2D& bounds) const;

private:
    EPenType fPenType;
    EPenBalance fPenBalance;
    GCoordinate fPenWidth;
};


/**
 * ICap encapsulates common functionality for frame Caps.
 * ICap encapsulates common functionality for frame Caps. Caps will only be created by the pen at points of Co (C - zero discontinuity).
 * Typically these include a Polyline, Polygon etc. A special pen can, however, change this default
 * behavior. The start and end points have caps attached.
 */

class ICap : public IMSTREAMABLE
{
	StreamableDeclarationsMacro(ICap);

protected :
	virtual void writeToStream(IDataStream& toWhere) const;
	virtual void readFromStream(IDataStream& toWhere);

public:
    /**	 The cap type -- an RTTI acceleration for known cap types. */
    enum ECapType {
		kFlush,
		kRound,
		kSquare,
		kUnknownCap
    };

	/**
	 * Constructs an ICap of the specified type.
	 */
    ICap(ECapType = kFlush);

	/**
	 * Copy constructor
	 */
    ICap(const ICap&);

    ~ICap();

	/**
	 * Returns the type of this cap.
	 */
    ECapType capType() const;

	/**
	 * Sets the type of this cap.
	 */
    void setCapType(ECapType capType);

	/**
	 * Assignment operator.
	 */
    ICap& operator=(const ICap& source);

	/**
	 * Tests two ICap objects for equality.
	 */
    virtual bool operator==(const ICap&) const;

	/**
	 * Tests two ICap for inequality.
	 */
    virtual bool operator!=(const ICap&) const;

private:
friend class IMGraphic;
friend class IGraph2DTestHelper;
	IGRect2D adjustBounds(const IGRect2D& bounds, const IPen* pen) const;

private:
    enum ECapType fCapType;
};


/**
 * IJoint encapsulates common functionality for frame Joints.
 * IJoint encapsulates common functionality for frame Joints.  Joints will only be created by the pen at points of Co (C - zero continuity).
 * Typically these include a Polyline, Polygon etc. A special pen can, however, change this default
 * behavior. The start and end points have caps attached.
 * In order to avoid polymorphic behavior for this class, the miterLimit has been added to
 * this class
 */

class IJoint : public IMSTREAMABLE
{
	StreamableDeclarationsMacro(IJoint);

protected :
	virtual void writeToStream(IDataStream& toWhere) const;
	virtual void readFromStream(IDataStream& toWhere);

public:
    /** Describes the type of joint. An RTTI acceleration for known joint types. */
    enum EJointType {
		kMiterLimit,
		kBevel,
		kRound,
		kUnknown
    };

	/**
	 * MiterLimit is 1.0 for all joints even though it is only applicable to the
	 * MiterLimit joint. For all other joints, the miter limit of 1.0 will be
	 * returned by the memberfunction miterLimit().
	 * This has been added in the class to avoid the use of polymorphism for simple
	 * classes such as Joints.
	 */
    IJoint(EJointType = kMiterLimit, GCoordinate miterLimit = 1.0);

    ~IJoint();

	/**
	 * Copy constructor.
	 */
    IJoint(const IJoint&);

	/**
	 * Assignment operator.
	 */
    IJoint& operator=(const IJoint& source);

	/**
	 * Returns the type of the joint.
	 */
    EJointType jointType() const;

	/**
	 * Returns the limit of the joint.
	 */
    GCoordinate	miterLimit() const;

	/**
	 * Sets the type and limit of the joint.
	 */
    void setJointType(EJointType type, GCoordinate mLimit = 1.0);

	/**
	 * Tests two IJoint objects for equality.
	 */
    virtual bool operator==(const IJoint&) const;

	/**
	 * Tests two IJoint objects for inequality.
	 */
    virtual bool operator!=(const IJoint&) const;

private:
friend class IMGraphic;
	IGRect2D adjustBounds(const IGRect2D& bounds, const IPen* pen) const;

private:
    EJointType fJointType;
    GCoordinate fmiterLimit;
};

/**
 * IImageTransferMode describes the behavior how source image is drawn at the destination.
 * IImageTransferMode describes the behavior how source image is drawn at the destination.
 * It applies for the geometry of IGImage.
 */

class IImageTransferMode : public IMSTREAMABLE
{
	StreamableDeclarationsMacro(IImageTransferMode);

protected :
	virtual void writeToStream(IDataStream& toWhere) const;
	virtual void readFromStream(IDataStream& toWhere);

public:
	/** Describes a set of image transfer modes. */
	enum EImageMode{
		kSrcCopy,
		kSrcORDst,
		kSrcANDDst,
		kSrcXORDst,
		kSrcANDInvertDst,
		kInvertSrc,
		kInvertResultOfSrcORDst,
		kSrcANDPattern,
		kInvertSrcORDst,
		kPatternCopy,
		kPatternORInvertSrcORDst,
		kPatternXORDst,
		kInvertDst,
		kAllZeros,
		kAllOnes,

//		Special for ICLUI: not really halftone, but filtered with a dither pattern
		kOCHalfTone
	};

/*
	The equivalent list from ICLUI:

	enum EImageMode {
		normal,
		sourcePaint,
		sourceAnd,
		sourceInvert,
		sourceErase,
		invert,
		notSourceErase,
		mergeCopy,
		mergePaint,
		patternCopy,
		patternPaint,
		patternInvert,
		destInvert,
		black,
		white,
		halftone
	};
*/

	/**
	 * Constructor with default behavior source-replaces-destination or source copy.
	 */
	IImageTransferMode();

	/**
	 * Copy constructor.
	 */
	IImageTransferMode(const IImageTransferMode&);

	/**
	 * Constructor takes an enumerated type EImageMode.
	 */
	IImageTransferMode(EImageMode mode);

	~IImageTransferMode();

	/**
	 * Returns the enumerated type of the transfer mode.
	 */
	IImageTransferMode::EImageMode mode() const;

	/**
	 * Assignment operator.
	 */
	IImageTransferMode& operator=(const IImageTransferMode&);

	/**
	 * Tests two IImageTransferMode objects for equality.
	 */
	virtual bool operator==(const IImageTransferMode&) const;

	/**
	 * Tests two IImageTransferMode objects for inequality.
	 */
	virtual bool operator!=(const IImageTransferMode&) const;

private:
	EImageMode fMode;
};

/**
 * IColorTransferMode describes how source color is drawn at the destination.
 * IColorTransferMode describes how source color is drawn at the destination.
 * It applies to color paint of fill, and frame of the geometry to render.
 */

class IColorTransferMode : public IMSTREAMABLE
{
	StreamableDeclarationsMacro(IColorTransferMode);

protected :
	virtual void writeToStream(IDataStream& toWhere) const;
	virtual void readFromStream(IDataStream& toWhere);

public:
	/** Describes a set of supported color transfer modes. */
	enum EColorMode {
		kSourceCopy,
		kInvertSource,
		kDestinationCopy,
		kInvertDestination,
		kOR,
		kAND,
		kXOR,
		kInvertedSourceAND,
		kInvertedSourceOR,
		kInvertedDestinationAND,
		kInvertedDestinationOR,
		kInvertedAND,
		kInvertedOR,
		kInvertedXOR,
		kONES,
		kZEROS
	};

/*
	The equivalent list in ICLUI:

	enum EColorMode {
		overPaint,
		notCopySource,
		leaveAlone,
		invert,
		or,
		and,
		xor,
		subtract,
		mergeNotSource,
		mergeSourceNot,
		maskSourceNot,
		notMaskSource,
		notMergeSource,
		notXorSource,
		white,
		black
	};
*/

	/**
	 * Constructor with default behavior source-replaces-destination or source copy.
	 */
	IColorTransferMode();

	/**
	 * Copy constructor.
	 */
	IColorTransferMode(const IColorTransferMode&);

	/**
	 * Constructor takes an enumerated type EColorMode.
	 */
	IColorTransferMode(EColorMode mode);

	~IColorTransferMode();

	/**
	 * Assignment operator.
	 */
	IColorTransferMode& operator=(const IColorTransferMode&);

	/**
	 * Returns the enumerated type of the transfer mode.
	 */
	IColorTransferMode::EColorMode mode() const;

	/**
	 * Tests two IColorTransferMode objects for equality.
	 */
	virtual bool operator==(const IColorTransferMode&) const;

	/**
	 * Tests two IColorTransferMode objects for inequality.
	 */
	virtual bool operator!=(const IColorTransferMode&) const;

private:
	EColorMode fMode;

};

/**
 * IImageSamplingControl lets you specify a filtering method to control the appearance of the rendered image when it has been interpolated or decimated.
 */

class IImageSamplingControl : public IMSTREAMABLE
{
	StreamableDeclarationsMacro(IImageSamplingControl);

protected :
	virtual void writeToStream(IDataStream& toWhere) const;
	virtual void readFromStream(IDataStream& toWhere);

public:
	/** Describes a set of supported image sampling control modes. */
	enum ESamplingMode
	{
		kBlackOnWhite,
		kWhiteOnBlack,
		kColorOnColor,
		kHalfTone
	};

	/**
	 * Constructor with default mode of color-on-color.
	 */
	IImageSamplingControl();

	/**
	 * Copy constructor.
	 */
	IImageSamplingControl(const IImageSamplingControl&);

	/**
	 * Constructor takes an enumerated type ESamplingMode.
	 */
	IImageSamplingControl(ESamplingMode mode);

	~IImageSamplingControl();

	/**
	 * Assignment operator.
	 */
	IImageSamplingControl& operator=(const IImageSamplingControl&);

	/**
	 * Returns the enumerated type of the sampling control mode.
	 */
	IImageSamplingControl::ESamplingMode mode() const;

	/**
	 * Tests two IImageSamplingControl objects for equality.
	 */
	virtual bool operator==(const IImageSamplingControl&) const;

	/**
	 * Tests two IImageSamplingControl objects for inequality.
	 */
	virtual bool operator!=(const IImageSamplingControl&) const;

private:
	ESamplingMode fMode;
};

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

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

#endif // _IGRAFATT_
