/*******************************************************************************
 * Copyright (c) 2000, 2012 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.theme;

import org.eclipse.swt.graphics.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.cairo.*;
import org.eclipse.swt.internal.gtk.*;

public class DrawData {
	public int style;
	public int[] state;
	public Rectangle clientArea;

	/** Part states */
	public static final int SELECTED = 1 << 1;
	public static final int FOCUSED = 1 << 2;
	public static final int PRESSED = 1 << 3;
	public static final int ACTIVE = 1 << 4;
	public static final int DISABLED = 1 << 5;
	public static final int HOT = 1 << 6;
	public static final int DEFAULTED = 1 << 7;
	public static final int GRAYED = 1 << 8;

	/** Text and Image drawing flags */
	public static final int DRAW_LEFT = 1 << 4;
	public static final int DRAW_TOP = 1 << 5;
	public static final int DRAW_RIGHT = 1 << 6;
	public static final int DRAW_BOTTOM = 1 << 7;
	public static final int DRAW_HCENTER = 1 << 8;
	public static final int DRAW_VCENTER = 1 << 9;

	/** Widget parts */
	public static final int WIDGET_NOWHERE = -1;
	public static final int WIDGET_WHOLE = 0;

	/** Scrollbar parts */
	public static final int SCROLLBAR_UP_ARROW = 1;
	public static final int SCROLLBAR_DOWN_ARROW = 2;
	public static final int SCROLLBAR_LEFT_ARROW = SCROLLBAR_UP_ARROW;
	public static final int SCROLLBAR_RIGHT_ARROW = SCROLLBAR_DOWN_ARROW;
	public static final int SCROLLBAR_UP_TRACK = 3;
	public static final int SCROLLBAR_DOWN_TRACK = 4;
	public static final int SCROLLBAR_LEFT_TRACK = SCROLLBAR_UP_TRACK;
	public static final int SCROLLBAR_RIGHT_TRACK = SCROLLBAR_DOWN_TRACK;
	public static final int SCROLLBAR_THUMB = 5;

	/** Scale parts */
	public static final int SCALE_UP_TRACK = 1;
	public static final int SCALE_LEFT_TRACK = SCALE_UP_TRACK;
	public static final int SCALE_DOWN_TRACK = 2;
	public static final int SCALE_RIGHT_TRACK = SCALE_DOWN_TRACK;
	public static final int SCALE_THUMB = 3;

	/** ToolItem parts */
	public static final int TOOLITEM_ARROW = 1;

	/** Combo parts */
	public static final int COMBO_ARROW = 1;


public DrawData() {
	state = new int[1];
}

Rectangle computeTrim(Theme theme, GC gc) {
	return new Rectangle(clientArea.x, clientArea.y, clientArea.width, clientArea.height);
}

void draw(Theme theme, GC gc, Rectangle bounds) {

}

void drawImage(Theme theme, Image image, GC gc, Rectangle bounds) {
	long /*int*/ drawable = gc.getGCData().drawable;
	Rectangle rect = image.getBounds();
	int state_type = getStateType(DrawData.WIDGET_WHOLE);
	if (state_type == OS.GTK_STATE_NORMAL) {
		gc.drawImage(image, 0, 0, rect.width, rect.height, bounds.x, bounds.y, bounds.width, bounds.height);
	} else {
		long /*int*/ pixbuf = ImageList.createPixbuf(image);
		long /*int*/ source = OS.gtk_icon_source_new();
		if (source != 0) {
			OS.gtk_icon_source_set_pixbuf(source, pixbuf);
			//TODO - always uses buttonHandle
			long /*int*/ buttonHandle = theme.buttonHandle;
			long /*int*/ gtkStyle = gtk_widget_get_style (buttonHandle);
			theme.transferClipping(gc, gtkStyle);
			long /*int*/ rendered = OS.gtk_style_render_icon(gtkStyle, source, OS.GTK_TEXT_DIR_NONE, state_type, -1, buttonHandle, null);
			OS.g_object_unref(pixbuf);
			//TODO - stretching
			if (rendered != 0) {
				if (OS.USE_CAIRO) {
					long /*int*/ cairo = OS.gdk_cairo_create (drawable);
					OS.gdk_cairo_set_source_pixbuf (cairo, gc.handle, 0, 0);
					Cairo.cairo_rectangle (cairo,bounds.x,bounds.y,bounds.width,bounds.height);
					Cairo.cairo_fill(cairo);
					Cairo.cairo_destroy(cairo);
				} else {
					OS.gdk_draw_pixbuf(drawable, gc.handle, rendered, 0, 0, bounds.x, bounds.y, bounds.width, bounds.height, OS.GDK_RGB_DITHER_NORMAL, 0, 0);
				}
				OS.g_object_unref(rendered);
			}
			OS.gtk_icon_source_free(source);
		}
	}
}

void drawText(Theme theme, String text, int flags, GC gc, Rectangle bounds) {
	long /*int*/ widget = getTextHandle(theme);
	long /*int*/ gtkStyle = gtk_widget_get_style(widget);
	long /*int*/ drawable = gc.getGCData().drawable;
	theme.transferClipping (gc, gtkStyle);
	byte[] buffer = Converter.wcsToMbcs(text, true);
	long /*int*/ layout = OS.gtk_widget_create_pango_layout(widget, buffer);
	int[] width = new int[1], height = new int[1];
	OS.pango_layout_get_pixel_size(layout, width, height);
	OS.pango_layout_set_width(layout, bounds.width * OS.PANGO_SCALE);
	int x = bounds.x;
	int y = bounds.y;
	if ((flags & DrawData.DRAW_LEFT) != 0) {
		OS.pango_layout_set_alignment(layout, OS.PANGO_ALIGN_LEFT);
	}
	if ((flags & DrawData.DRAW_HCENTER) != 0) {
		OS.pango_layout_set_alignment(layout, OS.PANGO_ALIGN_CENTER);
	}
	if ((flags & DrawData.DRAW_RIGHT) != 0) {
		OS.pango_layout_set_alignment(layout, OS.PANGO_ALIGN_RIGHT);
	}
	if ((flags & DrawData.DRAW_VCENTER) != 0) {
		y += (bounds.height - height[0]) / 2;
	}
	if ((flags & DrawData.DRAW_BOTTOM) != 0) {
		y += bounds.height - height[0];
	}
	int state_type = getStateType(DrawData.WIDGET_WHOLE);
	byte[] detail = Converter.wcsToMbcs("label", true);
	gtk_render_layout(gtkStyle, drawable, state_type, false, null, widget, detail, x, y, layout);
	OS.g_object_unref(layout);
}

Rectangle getBounds(int part, Rectangle bounds) {
	return new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height);
}

int getStateType(int part) {
	int state = this.state[part];
	int state_type = OS.GTK_STATE_NORMAL;
	if ((state & DrawData.DISABLED) != 0) {
		state_type = OS.GTK_STATE_INSENSITIVE;
	} else {
		if ((state & DrawData.SELECTED) != 0) state_type = OS.GTK_STATE_ACTIVE;
		if ((state & DrawData.HOT) != 0) {
			if ((state & DrawData.PRESSED) != 0) {
				state_type = OS.GTK_STATE_ACTIVE;
			} else {
				state_type = OS.GTK_STATE_PRELIGHT;
			}
		}
	}
	return state_type;
}

long /*int*/ getTextHandle(Theme theme) {
	return theme.labelHandle;
}

int hit(Theme theme, Point position, Rectangle bounds) {
	return -1;
}

Rectangle measureText(Theme theme, String text, int flags, GC gc, Rectangle bounds) {
	long /*int*/ widget = getTextHandle(theme);
	byte[] buffer = Converter.wcsToMbcs(text, true);
	long /*int*/ layout = OS.gtk_widget_create_pango_layout(widget, buffer);
	if (bounds != null) OS.pango_layout_set_width(layout, bounds.width);
	if ((flags & DrawData.DRAW_LEFT) != 0) {
		OS.pango_layout_set_alignment(layout, OS.PANGO_ALIGN_LEFT);
	}
	if ((flags & DrawData.DRAW_HCENTER) != 0) {
		OS.pango_layout_set_alignment(layout, OS.PANGO_ALIGN_CENTER);
	}
	if ((flags & DrawData.DRAW_RIGHT) != 0) {
		OS.pango_layout_set_alignment(layout, OS.PANGO_ALIGN_RIGHT);
	}
	int[] width = new int[1], height = new int[1];
	OS.pango_layout_get_pixel_size(layout, width, height);
	OS.g_object_unref(layout);
	return new Rectangle(0, 0, width[0], height[0]);
}

void gtk_render_frame (long /*int*/ style, long /*int*/ window, int state_type, int shadow_type, GdkRectangle area, long /*int*/ widget, byte[] detail, int x , int y, int width, int height) {
	if (OS.GTK3) {
		OS.gtk_render_frame (style, window, x, y, width, height);
	} else {
		OS.gtk_paint_flat_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
	}
}

void gtk_render_box (long /*int*/ style, long /*int*/ window, int state_type, int shadow_type, GdkRectangle area, long /*int*/ widget, byte[] detail, int x , int y, int width, int height) {
	if (OS.GTK3) {
		OS.gtk_render_frame (style, window, x, y, width, height);
		OS.gtk_render_background (style, window, x, y, width, height);
	} else {
		OS.gtk_paint_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
	}
}


void gtk_render_layout (long /*int*/ style, long /*int*/ window, int state_type, boolean use_text, GdkRectangle area, long /*int*/ widget, byte[] detail, int x , int y, long /*int*/ layout) {
	if (OS.GTK3) {
		OS.gtk_render_layout (style, window, x, y, layout);
	} else {
		OS.gtk_paint_layout (style, window, state_type, use_text, area, widget, detail, x , y, layout);
	}
}

void gtk_render_focus (long /*int*/ style, long /*int*/ window, int state_type, GdkRectangle area, long /*int*/ widget, byte[] detail, int x , int y, int width, int height) {
	if (OS.GTK3) {
		OS.gtk_style_context_save (style);
		OS.gtk_style_context_set_state (style, OS.gtk_widget_get_state_flags (widget));
		Cairo.cairo_save (window);
		OS.gtk_render_focus(style, window, x, y, width, height);
		Cairo.cairo_restore (window);
		OS.gtk_style_context_restore (style);

	} else {
		OS.gtk_paint_focus (style, window, state_type, area, widget, detail, x, y, width, height);
	}
}

void gtk_render_arrow(long /*int*/ style, long /*int*/ window, int state_type, int shadow_type, GdkRectangle area, long /*int*/ widget, byte[] detail, int arrow_type, boolean fill, int x, int y, int width, int height) {
	if (OS.GTK3) {
		double angle = 0;
		double size = 0;
		switch (arrow_type) {
			case OS.GTK_ARROW_UP:
				angle = 0;
				size = width;
				break;
			case OS.GTK_ARROW_RIGHT:
				angle = Math.PI/2;
				size = height;
				break;
			case OS.GTK_ARROW_DOWN:
				angle = Math.PI;
				size = width;
				break;
			case OS.GTK_ARROW_LEFT:
				angle = (3 * Math.PI)/2;
				size = height;
				break;
		}
		OS.gtk_style_context_set_state(style, state_type);
		OS.gtk_render_background(style, window, x, y, width, height);
		OS.gtk_render_frame (style, window, x, y, width, height);
		OS.gtk_render_arrow(style, window, angle, x, y, size);
	} else {
		OS.gtk_paint_arrow(style, window, state_type, shadow_type, area, widget, detail, arrow_type, fill, x, y, width, height);
	}
}

long /*int*/ gtk_widget_get_style(long /*int*/ handle) {
	return OS.GTK3 ? OS.gtk_widget_get_style_context(handle) : OS.gtk_widget_get_style(handle);
}


}
