/**************************************************************************\
* 
* Copyright (c) 2000, Microsoft Corp.  All Rights Reserved.
*
* Module Name:
* 
*    GdiplusLineCaps.h
*
* Abstract:
*
*   APIs for Custom Line Caps
*
\**************************************************************************/

#ifndef _GDIPLUSLINECAPS_H
#define _GDIPLUSLINECAPS_H

inline 
CustomLineCap::CustomLineCap(
    IN const GraphicsPath* fillPath,
    IN const GraphicsPath* strokePath,
    IN LineCap baseCap,
    IN REAL baseInset
    )
{
    nativeCap = NULL;
    GpPath* nativeFillPath = NULL;
    GpPath* nativeStrokePath = NULL;

    if(fillPath)
        nativeFillPath = fillPath->nativePath;
    if(strokePath)
        nativeStrokePath = strokePath->nativePath;

    lastResult = DllExports::GdipCreateCustomLineCap(
                    nativeFillPath, nativeStrokePath,
                    baseCap, baseInset, &nativeCap);
}

inline 
CustomLineCap::CustomLineCap()
{
    // This is used for default constructor for subclasses.
    // So don't create a nativeCap.

    nativeCap = NULL;
    lastResult = Ok;
}

inline 
CustomLineCap::~CustomLineCap()
{
    DllExports::GdipDeleteCustomLineCap(nativeCap);
}

inline Status 
CustomLineCap::SetStrokeCaps(
    IN LineCap startCap, 
    IN LineCap endCap)
{
    return SetStatus(DllExports::GdipSetCustomLineCapStrokeCaps(nativeCap,
                startCap, endCap));
}

inline Status 
CustomLineCap::GetStrokeCaps(
    OUT LineCap* startCap, 
    OUT LineCap* endCap) const
{
    return SetStatus(DllExports::GdipGetCustomLineCapStrokeCaps(nativeCap,
                 startCap, endCap));
}

inline Status 
CustomLineCap::SetStrokeJoin(
    IN LineJoin lineJoin)
{
    return SetStatus(DllExports::GdipSetCustomLineCapStrokeJoin(nativeCap, lineJoin));
}

inline LineJoin 
CustomLineCap::GetStrokeJoin() const
{
    LineJoin lineJoin;

    SetStatus(DllExports::GdipGetCustomLineCapStrokeJoin(nativeCap, &lineJoin));

    return lineJoin;
}

inline Status 
CustomLineCap::SetBaseCap(IN LineCap baseCap)
{
    return SetStatus(DllExports::GdipSetCustomLineCapBaseCap(nativeCap, baseCap));
}

inline LineCap 
CustomLineCap::GetBaseCap() const
{
    LineCap baseCap;
    SetStatus(DllExports::GdipGetCustomLineCapBaseCap(nativeCap, &baseCap));

    return baseCap;
}

inline Status 
CustomLineCap::SetBaseInset(IN REAL inset)
{
    return SetStatus(DllExports::GdipSetCustomLineCapBaseInset(nativeCap, inset));
}

inline REAL 
CustomLineCap::GetBaseInset() const
{
    REAL inset;
    SetStatus(DllExports::GdipGetCustomLineCapBaseInset(nativeCap, &inset));

    return inset;
}


inline Status 
CustomLineCap::SetWidthScale(IN REAL widthScale)
{
    return SetStatus(DllExports::GdipSetCustomLineCapWidthScale(nativeCap, widthScale));
}

inline REAL 
CustomLineCap::GetWidthScale() const
{
    REAL widthScale;
    SetStatus(DllExports::GdipGetCustomLineCapWidthScale(nativeCap, &widthScale));

    return widthScale;
}

inline CustomLineCap* 
CustomLineCap::Clone() const
{
    GpCustomLineCap *newNativeLineCap = NULL;
    
    SetStatus(DllExports::GdipCloneCustomLineCap(nativeCap, &newNativeLineCap));

    if (lastResult == Ok) 
    {
        CustomLineCap *newLineCap = new CustomLineCap(newNativeLineCap, lastResult);
        if (newLineCap == NULL) 
        {
            SetStatus(DllExports::GdipDeleteCustomLineCap(newNativeLineCap));
        }

        return newLineCap;
    }

    return NULL;
}

class AdjustableArrowCap : public CustomLineCap
{
public:

    AdjustableArrowCap(
        IN REAL height,
        IN REAL width,
        IN BOOL isFilled = TRUE
        )
    {
        GpAdjustableArrowCap* cap = NULL;

        lastResult = DllExports::GdipCreateAdjustableArrowCap(
                        height, width, isFilled, &cap);
        SetNativeCap(cap);
    }

    Status SetHeight(IN REAL height)
    {
        GpAdjustableArrowCap* cap = (GpAdjustableArrowCap*) nativeCap;
        return SetStatus(DllExports::GdipSetAdjustableArrowCapHeight(
                            cap, height));
    }

    REAL GetHeight() const
    {
        GpAdjustableArrowCap* cap = (GpAdjustableArrowCap*) nativeCap;
        REAL height;
        SetStatus(DllExports::GdipGetAdjustableArrowCapHeight(
                            cap, &height));

        return height;
    }

    Status SetWidth(IN REAL width)
    {
        GpAdjustableArrowCap* cap = (GpAdjustableArrowCap*) nativeCap;
        return SetStatus(DllExports::GdipSetAdjustableArrowCapWidth(
                            cap, width));
    }

    REAL GetWidth() const
    {
        GpAdjustableArrowCap* cap = (GpAdjustableArrowCap*) nativeCap;
        REAL width;
        SetStatus(DllExports::GdipGetAdjustableArrowCapWidth(
                            cap, &width));

        return width;
    }

    Status SetMiddleInset(IN REAL middleInset)
    {
        GpAdjustableArrowCap* cap = (GpAdjustableArrowCap*) nativeCap;
        return SetStatus(DllExports::GdipSetAdjustableArrowCapMiddleInset(
                            cap, middleInset));
    }

    REAL GetMiddleInset() const
    {
        GpAdjustableArrowCap* cap = (GpAdjustableArrowCap*) nativeCap;
        REAL middleInset;
        SetStatus(DllExports::GdipGetAdjustableArrowCapMiddleInset(
                            cap, &middleInset));

        return middleInset;
    }

    Status SetFillState(IN BOOL isFilled)
    {
        GpAdjustableArrowCap* cap = (GpAdjustableArrowCap*) nativeCap;
        return SetStatus(DllExports::GdipSetAdjustableArrowCapFillState(
                            cap, isFilled));
    }

    BOOL IsFilled() const
    {
        GpAdjustableArrowCap* cap = (GpAdjustableArrowCap*) nativeCap;
        BOOL isFilled;
        SetStatus(DllExports::GdipGetAdjustableArrowCapFillState(
                            cap, &isFilled));

        return isFilled;
    }

#ifdef DCR_USE_NEW_250932

private:
    AdjustableArrowCap(const AdjustableArrowCap &);
    AdjustableArrowCap& operator=(const AdjustableArrowCap &);

#endif

};

#endif