/*******************************************************************************
 * 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.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.cairo.Cairo;
import org.eclipse.swt.internal.gtk.*;

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


@Override
void draw(Theme theme, GC gc, Rectangle bounds) {
	int state = this.state[DrawData.WIDGET_WHOLE];

	long /*int*/ drawable = gc.getGCData().drawable;
	if ((style & SWT.RADIO) != 0) {
		long /*int*/ radioButtonHandle = theme.radioButtonHandle;
		long /*int*/ gtkStyle = OS.gtk_widget_get_style (radioButtonHandle);
		theme.transferClipping (gc, gtkStyle);
		int indicator_size = theme.getWidgetProperty(radioButtonHandle, "indicator-size");
		int indicator_spacing = theme.getWidgetProperty(radioButtonHandle, "indicator-spacing");
		int interior_focus = theme.getWidgetProperty(radioButtonHandle, "interior-focus");
		int focus_line_width = theme.getWidgetProperty(radioButtonHandle, "focus-line-width");
		int focus_padding = theme.getWidgetProperty(radioButtonHandle, "focus-padding");
		int border_width = OS.gtk_container_get_border_width(radioButtonHandle);
		
		int x = bounds.x + indicator_spacing + border_width;
		int y = bounds.y + (bounds.height - indicator_size) / 2;
		
		if (interior_focus == 0) {
			x += focus_line_width + focus_padding;
		}
		
		int shadow_type;
		if ((state & DrawData.GRAYED) != 0) {
			shadow_type = OS.GTK_SHADOW_ETCHED_IN;
		} else if ((state & DrawData.SELECTED) != 0) {
			shadow_type = OS.GTK_SHADOW_IN;
		} else {
			shadow_type = OS.GTK_SHADOW_OUT;
		}
		
		byte[] detail = Converter.wcsToMbcs(null, "radiobutton", true);
		if ((state & DrawData.HOT) != 0) {
			int prelight_x, prelight_y, prelight_width, prelight_height;
			prelight_x = bounds.x + border_width;
			prelight_y = bounds.y + border_width;
			prelight_width = bounds.width - (2 * border_width);
			prelight_height = bounds.height - (2 * border_width);
			gtk_render_frame (gtkStyle, drawable, OS.GTK_STATE_PRELIGHT, OS.GTK_SHADOW_ETCHED_OUT, null, radioButtonHandle, detail, prelight_x, prelight_y, prelight_width, prelight_height);
		}
		int state_type = getStateType(DrawData.WIDGET_WHOLE);
		OS.gtk_paint_option(gtkStyle, drawable, state_type, shadow_type, null, radioButtonHandle, detail, x, y, indicator_size, indicator_size);
		if (clientArea != null) {
			clientArea.x = bounds.x + 2 * indicator_spacing + border_width + indicator_size;
			clientArea.y = bounds.y + border_width;
			clientArea.width = bounds.width - (2 * indicator_spacing + 2 * border_width + indicator_size);
			clientArea.height = bounds.height - 2 * border_width;
		}
		return;
	}
	
	if ((style & SWT.CHECK) != 0) {
		long /*int*/ checkButtonHandle = theme.checkButtonHandle;
		long /*int*/ gtkStyle = OS.gtk_widget_get_style (checkButtonHandle);
		theme.transferClipping (gc, gtkStyle);
		int indicator_size = theme.getWidgetProperty(checkButtonHandle, "indicator-size");
		int indicator_spacing = theme.getWidgetProperty(checkButtonHandle, "indicator-spacing");
		int interior_focus = theme.getWidgetProperty(checkButtonHandle, "interior-focus");
		int focus_line_width = theme.getWidgetProperty(checkButtonHandle, "focus-line-width");
		int focus_padding = theme.getWidgetProperty(checkButtonHandle, "focus-padding");
		int border_width = OS.gtk_container_get_border_width(checkButtonHandle);
		
		int x = bounds.x + indicator_spacing + border_width;
		int y = bounds.y + (bounds.height - indicator_size) / 2;
		
		if (interior_focus == 0) {
			x += focus_line_width + focus_padding;
		}
		
		int shadow_type;
		if ((state & DrawData.GRAYED) != 0) {
			shadow_type = OS.GTK_SHADOW_ETCHED_IN;
		} else if ((state & DrawData.SELECTED) != 0) {
			shadow_type = OS.GTK_SHADOW_IN;
		} else {
			shadow_type = OS.GTK_SHADOW_OUT;
		}
		
		byte[] detail = Converter.wcsToMbcs(null, "checkbutton", true);
		if ((state & DrawData.HOT) != 0) {
			int prelight_x, prelight_y, prelight_width, prelight_height;
			prelight_x = bounds.x + border_width;
			prelight_y = bounds.y + border_width;
			prelight_width = bounds.width - (2 * border_width);
			prelight_height = bounds.height - (2 * border_width);
			gtk_render_frame (gtkStyle, drawable, OS.GTK_STATE_PRELIGHT, OS.GTK_SHADOW_ETCHED_OUT, null, checkButtonHandle, detail, prelight_x, prelight_y, prelight_width, prelight_height);
		}
		int state_type = getStateType(DrawData.WIDGET_WHOLE);
		gtk_render_check (gtkStyle, drawable, state_type, shadow_type, checkButtonHandle, detail, x, y, indicator_size, indicator_size);
		if (clientArea != null) {
			clientArea.x = bounds.x + 2 * indicator_spacing + border_width + indicator_size;
			clientArea.y = bounds.y + border_width;
			clientArea.width = bounds.width - (2 * indicator_spacing + 2 * border_width + indicator_size);
			clientArea.height = bounds.height - 2 * border_width;
		}
		return;
	}
	

	if ((style & SWT.PUSH) != 0) {
		long /*int*/ buttonHandle = theme.buttonHandle;
		long /*int*/ gtkStyle = OS.gtk_widget_get_style (buttonHandle);
		theme.transferClipping (gc, gtkStyle);		
		int focus_line_width = theme.getWidgetProperty(buttonHandle, "focus-line-width");
		int focus_padding = theme.getWidgetProperty(buttonHandle, "focus-padding");
		int border_width = OS.gtk_container_get_border_width(buttonHandle);
		
		GtkBorder default_border = new GtkBorder();
		long /*int*/ default_border_ptr = theme.getBorderProperty(buttonHandle, "default-border");
		if (default_border_ptr != 0) {
			OS.memmove(default_border, default_border_ptr, GtkBorder.sizeof);
			OS.gtk_border_free(default_border_ptr);
		} else {
			default_border.left = default_border.right = default_border.top = default_border.bottom = 1;
		}

		GtkBorder default_outside_border = new GtkBorder();
		long /*int*/ default_outside_border_ptr = theme.getBorderProperty(buttonHandle, "default-outside-border");
		if (default_outside_border_ptr != 0) {
			OS.memmove(default_outside_border, default_outside_border_ptr, GtkBorder.sizeof);
			OS.gtk_border_free(default_outside_border_ptr);
		} else {
			default_outside_border.left = default_outside_border.right = default_outside_border.top = default_outside_border.bottom = 0;
		}
		
		int x = bounds.x + border_width;
		int y = bounds.y + border_width;
		int width = bounds.width - border_width * 2;
		int height = bounds.height - border_width * 2;

		int relief = OS.gtk_button_get_relief(buttonHandle);
		byte[] detail = Converter.wcsToMbcs(null, (state & DrawData.DEFAULTED) != 0 ? "buttondefault" : "button", true);
		if ((state & DrawData.DEFAULTED) != 0 && relief == OS.GTK_RELIEF_NORMAL) {
			gtk_render_box (gtkStyle, drawable, OS.GTK_STATE_NORMAL, OS.GTK_SHADOW_IN, null, buttonHandle, detail, x, y, width, height);
            x += default_border.left;
            y += default_border.top;
            width -= default_border.left + default_border.right;
            height -= default_border.top + default_border.bottom;
		} else if ((state & DrawData.DEFAULTED) != 0) {
			x += default_outside_border.left;
			y += default_outside_border.top;
			width -= default_outside_border.left + default_outside_border.right;
			height -= default_outside_border.top + default_outside_border.bottom;
        }

		int shadow_type = OS.GTK_SHADOW_OUT;
		if ((state & (DrawData.SELECTED | DrawData.PRESSED)) != 0) shadow_type = OS.GTK_SHADOW_IN;
		int state_type = getStateType(DrawData.WIDGET_WHOLE);

		if (relief != OS.GTK_RELIEF_NONE || ((state & (DrawData.PRESSED | DrawData.HOT)) != 0)) {
			gtk_render_box (gtkStyle, drawable, state_type, shadow_type, null, buttonHandle, detail, x, y, width, height);
		}
		
	    if ((state & DrawData.FOCUSED) != 0) {
	    	int child_displacement_y = theme.getWidgetProperty(buttonHandle, "child-displacement-y");
	    	int child_displacement_x = theme.getWidgetProperty(buttonHandle, "child-displacement-x");
	    	int displace_focus = theme.getWidgetProperty(buttonHandle, "displace-focus");		    	
	    	int interior_focus = theme.getWidgetProperty(buttonHandle, "interior-focus");
	    	
	    	if (interior_focus != 0) {
	    		int xthickness = OS.gtk_style_get_xthickness(gtkStyle);
	    		int ythickness = OS.gtk_style_get_ythickness(gtkStyle);
	    		x += xthickness + focus_padding;
	            y += ythickness + focus_padding;
	            width -= 2 * (xthickness + focus_padding);
	            height -=  2 * (ythickness + focus_padding);
	    	} else {
	    		x -= focus_line_width + focus_padding;
	    		y -= focus_line_width + focus_padding;
	    		width += 2 * (focus_line_width + focus_padding);
	    		height += 2 * (focus_line_width + focus_padding);
	    	}
	    	
	    	if ((state & DrawData.PRESSED) != 0 && displace_focus != 0) {
	              x += child_displacement_x;
	              y += child_displacement_y;
	    	}
	    	
	    	gtk_render_focus (gtkStyle, drawable, state_type, null, buttonHandle, detail, x, y, width, height);
	    }
		if (clientArea != null) {
			clientArea.x = bounds.x + border_width;
			clientArea.y = bounds.y + border_width;
			clientArea.width = bounds.width - 2 * border_width;
			clientArea.height = bounds.height - 2 * border_width;
		}
	    return;
	}
}

@Override
int hit(Theme theme, Point position, Rectangle bounds) {
	return bounds.contains(position) ? DrawData.WIDGET_WHOLE : DrawData.WIDGET_NOWHERE;
}

void gtk_render_option (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) {
		long /*int*/ cairo = OS.gdk_cairo_create (window);
		long /*int*/ context = OS.gtk_widget_get_style_context (style);
		OS.gtk_render_option (context, cairo, x, y, width, height);
		Cairo.cairo_destroy (cairo);
	} else {
		OS.gtk_paint_option (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
	}
}

void gtk_render_check(long /*int*/ style, long /*int*/ window, int state_type, int shadow_type,  long /*int*/ widget, byte[] detail, int x , int y, int width, int height) {
	if (OS.GTK3) {
		long /*int*/ cairo = OS.gdk_cairo_create (window);
		long /*int*/ context = OS.gtk_widget_get_style_context (style);
		OS.gtk_render_check (context, cairo, x, y, width, height);
		Cairo.cairo_destroy (cairo);
	} else {
		OS.gtk_paint_check (style, window, state_type, shadow_type, null, widget, detail, x, y, width, height);
	}
}

}
