/*******************************************************************************
 * Copyright (c) 2000, 2011 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.internal;


import org.eclipse.swt.internal.win32.*;
import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;

public class ImageList {
	long /*int*/ handle;
	int style, refCount;
	Image [] images;

public ImageList (int style) {
	this (style, 32, 32);
}

public ImageList (int style, int width, int height) {
	this.style = style;
	int flags = OS.ILC_MASK;
	if (OS.IsWinCE) {
		flags |= OS.ILC_COLOR;
	} else {
		if (OS.COMCTL32_MAJOR >= 6) {
			flags |= OS.ILC_COLOR32;
		} else {
			long /*int*/ hDC = OS.GetDC (0);
			int bits = OS.GetDeviceCaps (hDC, OS.BITSPIXEL);
			int planes = OS.GetDeviceCaps (hDC, OS.PLANES);
			OS.ReleaseDC (0, hDC);
			int depth = bits * planes;
			switch (depth) {
				case 4: flags |= OS.ILC_COLOR4; break;
				case 8: flags |= OS.ILC_COLOR8; break;
				case 16: flags |= OS.ILC_COLOR16; break;
				case 24: flags |= OS.ILC_COLOR24; break;
				case 32: flags |= OS.ILC_COLOR32; break;
				default: flags |= OS.ILC_COLOR; break;
			}
		}
	}
	if ((style & SWT.RIGHT_TO_LEFT) != 0) flags |= OS.ILC_MIRROR;
	handle = OS.ImageList_Create (width, height, flags, 16, 16);
	images = new Image [4];
}

public int add (Image image) {
	int count = OS.ImageList_GetImageCount (handle);
	int index = 0;
	while (index < count) {
		if (images [index] != null) {
			if (images [index].isDisposed ()) images [index] = null;
		}
		if (images [index] == null) break;
		index++;
	}
	if (count == 0) {
		Rectangle rect = image.getBounds ();
		OS.ImageList_SetIconSize (handle, rect.width, rect.height);
	}
	set (index, image, count);
	if (index == images.length) {
		Image [] newImages = new Image [images.length + 4];
		System.arraycopy (images, 0, newImages, 0, images.length);
		images = newImages;
	}
	images [index] = image;
	return index;
}

public int addRef() {
	return ++refCount;
}

long /*int*/ copyBitmap (long /*int*/ hImage, int width, int height) {
	BITMAP bm = new BITMAP ();
	OS.GetObject (hImage, BITMAP.sizeof, bm);
	long /*int*/ hDC = OS.GetDC (0);
	long /*int*/ hdc1 = OS.CreateCompatibleDC (hDC);
	OS.SelectObject (hdc1, hImage);
	long /*int*/ hdc2 = OS.CreateCompatibleDC (hDC);
	/*
	* Feature in Windows.  If a bitmap has a 32-bit depth and any
	* pixel has an alpha value different than zero, common controls
	* version 6.0 assumes that the bitmap should be alpha blended.
	* AlphaBlend() composes the alpha channel of a destination 32-bit
	* depth image with the alpha channel of the source image. This
	* may cause opaque images to draw transparently.  The fix is
	* remove the alpha channel of opaque images by down sampling
	* it to 24-bit depth.
	*/
	long /*int*/ hBitmap;
	if (bm.bmBitsPixel == 32 && OS.COMCTL32_MAJOR >= 6) {
		BITMAPINFOHEADER bmiHeader = new BITMAPINFOHEADER();
		bmiHeader.biSize = BITMAPINFOHEADER.sizeof;
		bmiHeader.biWidth = width;
		bmiHeader.biHeight = -height;
		bmiHeader.biPlanes = 1;
		bmiHeader.biBitCount = (short)24;
		if (OS.IsWinCE) bmiHeader.biCompression = OS.BI_BITFIELDS;
		else bmiHeader.biCompression = OS.BI_RGB;
		byte[] bmi = new byte[BITMAPINFOHEADER.sizeof + (OS.IsWinCE ? 12 : 0)];
		OS.MoveMemory(bmi, bmiHeader, BITMAPINFOHEADER.sizeof);
		/* Set the rgb colors into the bitmap info */
		if (OS.IsWinCE) {
			int redMask = 0xFF00;
			int greenMask = 0xFF0000;
			int blueMask = 0xFF000000;
			/* big endian */
			int offset = BITMAPINFOHEADER.sizeof;
			bmi[offset] = (byte)((redMask & 0xFF000000) >> 24);
			bmi[offset + 1] = (byte)((redMask & 0xFF0000) >> 16);
			bmi[offset + 2] = (byte)((redMask & 0xFF00) >> 8);
			bmi[offset + 3] = (byte)((redMask & 0xFF) >> 0);
			bmi[offset + 4] = (byte)((greenMask & 0xFF000000) >> 24);
			bmi[offset + 5] = (byte)((greenMask & 0xFF0000) >> 16);
			bmi[offset + 6] = (byte)((greenMask & 0xFF00) >> 8);
			bmi[offset + 7] = (byte)((greenMask & 0xFF) >> 0);
			bmi[offset + 8] = (byte)((blueMask & 0xFF000000) >> 24);
			bmi[offset + 9] = (byte)((blueMask & 0xFF0000) >> 16);
			bmi[offset + 10] = (byte)((blueMask & 0xFF00) >> 8);
			bmi[offset + 11] = (byte)((blueMask & 0xFF) >> 0);
		}
		long /*int*/[] pBits = new long /*int*/[1];
		hBitmap = OS.CreateDIBSection(0, bmi, OS.DIB_RGB_COLORS, pBits, 0, 0);
	} else {
		hBitmap = OS.CreateCompatibleBitmap (hDC, width, height);
	}
	OS.SelectObject (hdc2, hBitmap);
	if (width != bm.bmWidth || height != bm.bmHeight) {
		if (!OS.IsWinCE) OS.SetStretchBltMode(hdc2, OS.COLORONCOLOR);
		OS.StretchBlt (hdc2, 0, 0, width, height, hdc1, 0, 0, bm.bmWidth, bm.bmHeight, OS.SRCCOPY);
	} else {
		OS.BitBlt (hdc2, 0, 0, width, height, hdc1, 0, 0, OS.SRCCOPY);
	}
	OS.DeleteDC (hdc1);
	OS.DeleteDC (hdc2);
	OS.ReleaseDC (0, hDC);
	return hBitmap;
}

long /*int*/ copyIcon (long /*int*/ hImage, int width, int height) {
	if (OS.IsWinCE) SWT.error(SWT.ERROR_NOT_IMPLEMENTED);
	long /*int*/ hIcon = OS.CopyImage (hImage, OS.IMAGE_ICON, width, height, 0);
	return hIcon != 0 ? hIcon : hImage;
}

long /*int*/ copyWithAlpha (long /*int*/ hBitmap, int background, byte[] alphaData, int destWidth, int destHeight) {
	BITMAP bm = new BITMAP ();
	OS.GetObject (hBitmap, BITMAP.sizeof, bm);
	int srcWidth = bm.bmWidth;
	int srcHeight = bm.bmHeight;
	
	/* Create resources */
	long /*int*/ hdc = OS.GetDC (0);
	long /*int*/ srcHdc = OS.CreateCompatibleDC (hdc);
	long /*int*/ oldSrcBitmap = OS.SelectObject (srcHdc, hBitmap);
	long /*int*/ memHdc = OS.CreateCompatibleDC (hdc);
	BITMAPINFOHEADER bmiHeader = new BITMAPINFOHEADER ();
	bmiHeader.biSize = BITMAPINFOHEADER.sizeof;
	bmiHeader.biWidth = srcWidth;
	bmiHeader.biHeight = -srcHeight;
	bmiHeader.biPlanes = 1;
	bmiHeader.biBitCount = 32;
	bmiHeader.biCompression = OS.BI_RGB;
	byte []	bmi = new byte[BITMAPINFOHEADER.sizeof];
	OS.MoveMemory (bmi, bmiHeader, BITMAPINFOHEADER.sizeof);
	long /*int*/ [] pBits = new long /*int*/ [1];
	long /*int*/ memDib = OS.CreateDIBSection (0, bmi, OS.DIB_RGB_COLORS, pBits, 0, 0);
	if (memDib == 0) SWT.error (SWT.ERROR_NO_HANDLES);
	long /*int*/ oldMemBitmap = OS.SelectObject (memHdc, memDib);

	BITMAP dibBM = new BITMAP ();
	OS.GetObject (memDib, BITMAP.sizeof, dibBM);
	int sizeInBytes = dibBM.bmWidthBytes * dibBM.bmHeight;

 	/* Get the foreground pixels */
 	OS.BitBlt (memHdc, 0, 0, srcWidth, srcHeight, srcHdc, 0, 0, OS.SRCCOPY);
 	byte[] srcData = new byte [sizeInBytes];
	OS.MoveMemory (srcData, dibBM.bmBits, sizeInBytes);
	
	/* Merge the alpha channel in place */
	if (alphaData != null) {
		int spinc = dibBM.bmWidthBytes - srcWidth * 4;
		int ap = 0, sp = 3;
		for (int y = 0; y < srcHeight; ++y) {
			for (int x = 0; x < srcWidth; ++x) {
				srcData [sp] = alphaData [ap++];
				sp += 4;
			}
			sp += spinc;
		}
	} else {
		byte transRed = (byte)(background & 0xFF);
		byte transGreen = (byte)((background >> 8) & 0xFF);
		byte transBlue = (byte)((background >> 16) & 0xFF);
		final int spinc = dibBM.bmWidthBytes - srcWidth * 4;
		int sp = 3;
		for (int y = 0; y < srcHeight; ++y) {
			for (int x = 0; x < srcWidth; ++x) {
				srcData [sp] = (srcData[sp-1] == transRed && srcData[sp-2] == transGreen && srcData[sp-3] == transBlue) ? 0 : (byte)255;
				sp += 4;
			}
			sp += spinc;
		}
	}
	OS.MoveMemory (dibBM.bmBits, srcData, sizeInBytes);
	
	/* Stretch and free resources */
	if (srcWidth != destWidth || srcHeight != destHeight) {
		BITMAPINFOHEADER bmiHeader2 = new BITMAPINFOHEADER ();
		bmiHeader2.biSize = BITMAPINFOHEADER.sizeof;
		bmiHeader2.biWidth = destWidth;
		bmiHeader2.biHeight = -destHeight;
		bmiHeader2.biPlanes = 1;
		bmiHeader2.biBitCount = 32;
		bmiHeader2.biCompression = OS.BI_RGB;
		byte []	bmi2 = new byte[BITMAPINFOHEADER.sizeof];
		OS.MoveMemory (bmi2, bmiHeader2, BITMAPINFOHEADER.sizeof);
		long /*int*/ [] pBits2 = new long /*int*/ [1];
		long /*int*/ memDib2 = OS.CreateDIBSection (0, bmi2, OS.DIB_RGB_COLORS, pBits2, 0, 0);
		long /*int*/ memHdc2 = OS.CreateCompatibleDC (hdc);
		long /*int*/ oldMemBitmap2 = OS.SelectObject (memHdc2, memDib2);
		if (!OS.IsWinCE) OS.SetStretchBltMode(memHdc2, OS.COLORONCOLOR);
		OS.StretchBlt (memHdc2, 0, 0, destWidth, destHeight, memHdc, 0, 0, srcWidth, srcHeight, OS.SRCCOPY);
		OS.SelectObject (memHdc2, oldMemBitmap2);
		OS.DeleteDC (memHdc2);
		OS.SelectObject (memHdc, oldMemBitmap);
		OS.DeleteDC (memHdc);
		OS.DeleteObject (memDib);
		memDib = memDib2;
	} else {
		OS.SelectObject (memHdc, oldMemBitmap);
		OS.DeleteDC (memHdc);
	}
	OS.SelectObject (srcHdc, oldSrcBitmap);
	OS.DeleteDC (srcHdc);
	OS.ReleaseDC (0, hdc);
	return memDib;
}

long /*int*/ createMaskFromAlpha (ImageData data, int destWidth, int destHeight) {
	int srcWidth = data.width;
	int srcHeight = data.height;
	ImageData mask = ImageData.internal_new (srcWidth, srcHeight, 1,
			new PaletteData(new RGB [] {new RGB (0, 0, 0), new RGB (0xff, 0xff, 0xff)}),
			2, null, 1, null, null, -1, -1, -1, 0, 0, 0, 0);
	int ap = 0;
	for (int y = 0; y < mask.height; y++) {
		for (int x = 0; x < mask.width; x++) {
			mask.setPixel (x, y, (data.alphaData [ap++] & 0xff) <= 127 ? 1 : 0);
		}
	}
	long /*int*/ hMask = OS.CreateBitmap (srcWidth, srcHeight, 1, 1, mask.data);
	if (srcWidth != destWidth || srcHeight != destHeight) {
		long /*int*/ hdc = OS.GetDC (0);
		long /*int*/ hdc1 = OS.CreateCompatibleDC (hdc);
		OS.SelectObject (hdc1, hMask);
		long /*int*/ hdc2 = OS.CreateCompatibleDC (hdc);
		long /*int*/ hMask2 = OS.CreateBitmap (destWidth, destHeight, 1, 1, null);
		OS.SelectObject (hdc2, hMask2);
		if (!OS.IsWinCE) OS.SetStretchBltMode(hdc2, OS.COLORONCOLOR);
		OS.StretchBlt (hdc2, 0, 0, destWidth, destHeight, hdc1, 0, 0, srcWidth, srcHeight, OS.SRCCOPY);
		OS.DeleteDC (hdc1);
		OS.DeleteDC (hdc2);
		OS.ReleaseDC (0, hdc);
		OS.DeleteObject(hMask);
		hMask = hMask2;
	}
	return hMask;
}

long /*int*/ createMask (long /*int*/ hBitmap, int destWidth, int destHeight, int background, int transparentPixel) {
	BITMAP bm = new BITMAP ();
	OS.GetObject (hBitmap, BITMAP.sizeof, bm);
	int srcWidth = bm.bmWidth;
	int srcHeight = bm.bmHeight;
	long /*int*/ hMask = OS.CreateBitmap (destWidth, destHeight, 1, 1, null);
	long /*int*/ hDC = OS.GetDC (0);
	long /*int*/ hdc1 = OS.CreateCompatibleDC (hDC);
	if (background != -1) {
		OS.SelectObject (hdc1, hBitmap);
		
		/*
		* If the image has a palette with multiple entries having
		* the same color and one of those entries is the transparentPixel,
		* only the first entry becomes transparent. To avoid this
		* problem, temporarily change the image palette to a palette
		* where the transparentPixel is white and everything else is
		* black. 
		*/
		boolean isDib = bm.bmBits != 0;
		byte[] originalColors = null;
		if (!OS.IsWinCE && transparentPixel != -1 && isDib && bm.bmBitsPixel <= 8) {
			int maxColors = 1 << bm.bmBitsPixel;
			byte[] oldColors = new byte[maxColors * 4];
			OS.GetDIBColorTable(hdc1, 0, maxColors, oldColors);
			int offset = transparentPixel * 4;
			byte[] newColors = new byte[oldColors.length];
			newColors[offset] = (byte)0xFF;
			newColors[offset+1] = (byte)0xFF;
			newColors[offset+2] = (byte)0xFF;
			OS.SetDIBColorTable(hdc1, 0, maxColors, newColors);
			originalColors = oldColors;
			OS.SetBkColor (hdc1, 0xFFFFFF);
		} else {
			OS.SetBkColor (hdc1, background);
		}
		
		long /*int*/ hdc2 = OS.CreateCompatibleDC (hDC);
		OS.SelectObject (hdc2, hMask);
		if (destWidth != srcWidth || destHeight != srcHeight) {
			if (!OS.IsWinCE) OS.SetStretchBltMode (hdc2, OS.COLORONCOLOR);
			OS.StretchBlt (hdc2, 0, 0, destWidth, destHeight, hdc1, 0, 0, srcWidth, srcHeight, OS.SRCCOPY);
		} else {
			OS.BitBlt (hdc2, 0, 0, destWidth, destHeight, hdc1, 0, 0, OS.SRCCOPY);
		}
		OS.DeleteDC (hdc2);

		/* Put back the original palette */
		if (originalColors != null) OS.SetDIBColorTable(hdc1, 0, 1 << bm.bmBitsPixel, originalColors);
	} else {
		long /*int*/ hOldBitmap = OS.SelectObject (hdc1, hMask);
		OS.PatBlt (hdc1, 0, 0, destWidth, destHeight, OS.BLACKNESS);
		OS.SelectObject (hdc1, hOldBitmap);
	}
	OS.ReleaseDC (0, hDC);
	OS.DeleteDC (hdc1);
	return hMask;
}

public void dispose () {
	if (handle != 0) OS.ImageList_Destroy (handle);
	handle = 0;
	images = null;
}

public Image get (int index) {
	return images [index];
}

public int getStyle () {
	return style;
}

public long /*int*/ getHandle () {
	return handle;
}

public Point getImageSize() {
	int [] cx = new int [1], cy = new int [1];
	OS.ImageList_GetIconSize (handle, cx, cy);
	return new Point (cx [0], cy [0]);
}

public int indexOf (Image image) {
	int count = OS.ImageList_GetImageCount (handle);
	for (int i=0; i<count; i++) {
		if (images [i] != null) {
			if (images [i].isDisposed ()) images [i] = null;
			if (images [i] != null && images [i].equals (image)) return i;
		}
	}
	return -1;
}

public void put (int index, Image image) {
	int count = OS.ImageList_GetImageCount (handle);
	if (!(0 <= index && index < count)) return;
	if (image != null) set(index, image, count);
	images [index] = image;
}

public void remove (int index) {
	int count = OS.ImageList_GetImageCount (handle);
	if (!(0 <= index && index < count)) return;
	OS.ImageList_Remove (handle, index);
	System.arraycopy (images, index + 1, images, index, --count - index);
	images [index] = null;
}

public int removeRef() {
	return --refCount;
}

void set (int index, Image image, int count) {
	long /*int*/ hImage = image.handle;
	int [] cx = new int [1], cy = new int [1];
	OS.ImageList_GetIconSize (handle, cx, cy);
	switch (image.type) {
		case SWT.BITMAP: {
			/*
			* Note that the image size has to match the image list icon size. 
			*/
			long /*int*/ hBitmap = 0, hMask = 0;
			ImageData data = image.getImageData ();
			switch (data.getTransparencyType ()) {
				case SWT.TRANSPARENCY_ALPHA:
					if (OS.COMCTL32_MAJOR >= 6) {
						hBitmap = copyWithAlpha (hImage, -1, data.alphaData, cx [0], cy [0]);
					} else {
						hBitmap = copyBitmap (hImage, cx [0], cy [0]);
						hMask = createMaskFromAlpha (data, cx [0], cy [0]);
					}
					break;
				case SWT.TRANSPARENCY_PIXEL:
					int background = -1;
					Color color = image.getBackground ();
					if (color != null) background = color.handle;
					hBitmap = copyBitmap (hImage, cx [0], cy [0]);
					hMask = createMask (hImage, cx [0], cy [0], background, data.transparentPixel);
					break;
				case SWT.TRANSPARENCY_NONE:
				default:
					hBitmap = copyBitmap (hImage, cx [0], cy [0]);
					if (index != count) hMask = createMask (hImage, cx [0], cy [0], -1, -1);
					break;
			}
			if (index == count) {
				OS.ImageList_Add (handle, hBitmap, hMask);
			} else {
				/* Note that the mask must always be replaced even for TRANSPARENCY_NONE */
				OS.ImageList_Replace (handle, index, hBitmap, hMask);
			}
			if (hMask != 0) OS.DeleteObject (hMask);
			if (hBitmap != hImage) OS.DeleteObject (hBitmap);
			break;
		}
		case SWT.ICON: {
			if (OS.IsWinCE) {	
				OS.ImageList_ReplaceIcon (handle, index == count ? -1 : index, hImage);
			} else {
				long /*int*/ hIcon = copyIcon (hImage, cx [0], cy [0]);
				OS.ImageList_ReplaceIcon (handle, index == count ? -1 : index, hIcon);
				OS.DestroyIcon (hIcon);
			}
			break;
		}
	}
}

public int size () {
	int result = 0;
	int count = OS.ImageList_GetImageCount (handle);
	for (int i=0; i<count; i++) {
		if (images [i] != null) {
			if (images [i].isDisposed ()) images [i] = null;
			if (images [i] != null) result++;
		}
	}
	return result;
}

}
