/*
 * Copyright (c) 2000-2009 TeamDev Ltd. All rights reserved.
 * TeamDev PROPRIETARY and CONFIDENTIAL.
 * Use is subject to license terms.
 */
package com.jniwrapper.win32.gdi;

import com.jniwrapper.*;
import com.jniwrapper.util.EnumItem;
import com.jniwrapper.util.FlagSet;
import com.jniwrapper.win32.FunctionName;
import com.jniwrapper.win32.Handle;
import com.jniwrapper.win32.LastErrorException;

// TODO [leha]: Register GdiObjects with NativeResource collector. Make sure that stock objects are not destroyed!!!
/**
 * An abstract base for all GDI objects.
 * 
 * @author Alexander Evsukov
 */
abstract public class GdiObject extends Handle
{
    /*
     * GDI error constants
     */
    public static final int GDI_ERROR = 0xFFFFFFFF;
    public static final int HGDI_ERROR = 0xFFFFFFFF;

    static final FunctionName FUNCTION_GET_OBJECT = new FunctionName("GetObject");
    static final String FUNCTION_DELETE_OBJECT = "DeleteObject";
    static final String FUNCTION_GET_OBJECT_TYPE = "GetObjectType";

    /**
     * Class ImageType represents the enumeration of windows image types.
     */
    public static class ImageType extends EnumItem
    {
        /**
         * The image is bitmap
         */
        public static final ImageType BITMAP = new ImageType(0);
        /**
         * The image is icon
         */
        public static final ImageType ICON = new ImageType(1);
        /**
         * The image is cursor
         */
        public static final ImageType CURSOR = new ImageType(2);
        /**
         * The image is enhanced metafile 
         */
        public static final ImageType ENHMETAFILE = new ImageType(3);

        private ImageType(int value)
        {
            super(value);
        }
    }

    /**
     * ImageLoadParameters class.
     */
    public static class ImageLoadParameters extends FlagSet
    {
        /**
         * The default flag, it does nothing. All it means is "not {@link com.jniwrapper.win32.gdi.GdiObject.ImageLoadParameters#MONOCHROME}".
         */
        public static final int DEFAULTCOLOR = 0x0000;
        /**
         * The image in black and white colors.
         */
        public static final int MONOCHROME = 0x0001;
        /**
         * The image in color.
          */
        public static final int COLOR = 0x0002;
        /**
         * Returns the original image handle if it satisfies the criteria for the copy.
         */
        public static final int COPYRETURNORG = 0x0004;
        /**
         * Deletes the original image after creating the copy.
          */
        public static final int COPYDELETEORG = 0x0008;
        /**
         * Loads the stand-alone image from the file.
         */
        public static final int LOADFROMFILE = 0x0010;
        /**
         * Retrieves the color value of the first pixel in the image and replaces the corresponding entry in the color
         * table with the default window color. All pixels in the image that use that entry become the default window color.
         * This value applies only to images that have corresponding color tables.
         * Do not use this option if you are loading a bitmap with a color depth greater than 8 bit per pixel.
         */
        public static final int LOADTRANSPARENT = 0x0020;
        /**
         * Uses the width or height specified by the system metric values.
         */
        public static final int DEFAULTSIZE = 0x0040;
        /**
         * Uses true VGA colors.
         */
        public static final int VGACOLOR = 0x0080;
        /**
         * Searches the color table for the image and replaces the shades of gray with the corresponding 3-D color. 
         */
        public static final int LOADMAP3DCOLORS = 0x1000;
        /**
         * Causes function to return a DIB section bitmap rather than a compatible bitmap.
         */
        public static final int CREATEDIBSECTION = 0x2000;
        /**
         * Tries to reload an icon or cursor resource from the original resource file rather than simply copying the current image.
         */
        public static final int COPYFROMRESOURCE = 0x4000;
        /**
         * Shares the image handle if the image is loaded multiple times.
         */
        public static final int SHARED = 0x8000;
    }

    public GdiObject()
    {
    }

    public GdiObject(long value)
    {
        super(value);
    }

    public void deleteObject()
    {
        final Function function = Gdi32.getInstance().getFunction(FUNCTION_DELETE_OBJECT);
        Bool result = new Bool();
        long errorCode = function.invoke(result, this);
        if (!result.getValue())
        {
            throw new LastErrorException(errorCode, "Failed to delete object");
        }
    }

    public long getObject(GdiObject object, Parameter data)
    {
        final Function function = Gdi32.getInstance().getFunction(FUNCTION_GET_OBJECT.toString());
        Int result = new Int();
        final int length = data.getLength();
        long errorCode = function.invoke(result, object, new Int(length), new Pointer(data));
        if ((result.getValue() == 0) || length != result.getValue())
        {
            throw new LastErrorException(errorCode, "Failed to get object.");
        }
        return result.getValue();
    }

    /**
     * GdiObjectType class represents the enumeration of standard GDI object types.
     */
    public static class Type extends EnumItem
    {
        /**
         * The object is pen
         */
        public static final Type PEN = new Type(1);
        /**
         * The object is brush
         */
        public static final Type BRUSH = new Type(2);
        /**
         * The object is device context
         */
        public static final Type DC = new Type(3);
        /**
         * The object is metafile device context
         */
        public static final Type METADC = new Type(4);
        /**
         * The object is palette
         */
        public static final Type PAL = new Type(5);
        /**
         * The object is font
         */
        public static final Type FONT = new Type(6);
        /**
         * The object is bitmap
         */
        public static final Type BITMAP = new Type(7);
        /**
         * The object is region
         */
        public static final Type REGION = new Type(8);
        /**
         * The object is metafile
         */
        public static final Type METAFILE = new Type(9);
        /**
         * The object is memory device context
         */
        public static final Type MEMDC = new Type(10);
        /**
         * The object is extended pen
         */
        public static final Type EXTPEN = new Type(11);
        /**
         * The object is enhanced metafile device context
         */
        public static final Type ENHMETADC = new Type(12);
        /**
         * The object is enhanced metafile
         */
        public static final Type ENHMETAFILE = new Type(13);

        private Type(int value)
        {
            super(value);
        }
    }

    /**
     * Returns GDI object type.
     * 
     * @return object type
     */
    public Type getObjectType()
    {
        UInt32 result = new UInt32();
        final Function function = Gdi32.getInstance().getFunction(FUNCTION_GET_OBJECT_TYPE);
        function.invoke(result, this);
        return new Type((int)result.getValue());
    }
}