/*******************************************************************************
 * 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.gtk.*;

public class ToolItemDrawData extends DrawData {

	public ToolBarDrawData parent;

	static final int ARROW_WIDTH = 8;
	static final int ARROW_HEIGHT = 6;

public ToolItemDrawData() {
	state = new int[2];
}

@Override
Rectangle computeTrim(Theme theme, GC gc) {
	long /*int*/ buttonHandle = theme.buttonHandle;
	long /*int*/ gtkStyle = gtk_widget_get_style(buttonHandle);
	int focus_width = theme.getWidgetProperty(buttonHandle, "focus-line-width");
	int focus_padding = theme.getWidgetProperty(buttonHandle, "focus-padding");
	int xthickness = OS.gtk_style_get_xthickness(gtkStyle);
	int ythickness = OS.gtk_style_get_ythickness(gtkStyle);
	int borderX = xthickness + focus_width + focus_padding;
	int borderY = ythickness + focus_width + focus_padding;
	int x = clientArea.x - borderX;
	int y = clientArea.y - borderY;
	int width = clientArea.width + 2 * borderX;
	int height = clientArea.height + 2 * borderY;
	if ((style & SWT.DROP_DOWN) != 0) {
		width += ARROW_WIDTH;
	}
	return new Rectangle(x, y, width, height);
}

@Override
void draw(Theme theme, GC gc, Rectangle bounds) {
	int state = this.state[DrawData.WIDGET_WHOLE];
	long /*int*/ drawable = OS.GTK3 ? gc.getGCData().cairo : gc.getGCData().drawable;

	if ((style & SWT.SEPARATOR) != 0) {
		int state_type = getStateType(DrawData.WIDGET_WHOLE);
		long /*int*/ separatorHandle = theme.separatorHandle;
		byte[] detail = Converter.wcsToMbcs("vseparator", true);
		long /*int*/ gtkStyle = gtk_widget_get_style (separatorHandle);
		theme.transferClipping(gc, gtkStyle);
		if ((parent.style & SWT.VERTICAL) != 0) {
			if (OS.GTK3) {
				OS.gtk_render_line (gtkStyle, drawable, bounds.x, bounds.y + bounds.height / 2, bounds.x + bounds.width, bounds.y + bounds.height / 2);
			} else {
				OS.gtk_paint_hline(gtkStyle, drawable, state_type, null, separatorHandle, detail, bounds.x, bounds.x + bounds.width, bounds.y + bounds.height / 2);
			}
		} else {
			if (OS.GTK3) {
				OS.gtk_render_line (gtkStyle, drawable, bounds.x + bounds.width / 2, bounds.y, bounds.x + bounds.width / 2, bounds.y + bounds.height);
			} else {
				OS.gtk_paint_vline(gtkStyle, drawable, state_type, null, separatorHandle, detail, bounds.y, bounds.y + bounds.height, bounds.x + bounds.width / 2);
			}
		}
		return;
	}

	long /*int*/ buttonHandle = theme.buttonHandle;
	long /*int*/ gtkStyle = 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);

	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;

	byte[] detail = null;
	if ((style & (SWT.PUSH | SWT.DROP_DOWN)) != 0) {
		detail = Converter.wcsToMbcs("button", true);
	} else if ((style & (SWT.CHECK | SWT.RADIO)) != 0) {
		detail = Converter.wcsToMbcs("togglebutton", true);
	}

	int[] relief = new int[1];
	long /*int*/ toolbarHandle = theme.toolbarHandle;
	OS.gtk_widget_style_get(toolbarHandle, OS.button_relief, relief, 0);

	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[0] != OS.GTK_RELIEF_NONE || ((state & (DrawData.PRESSED | DrawData.HOT | DrawData.SELECTED)) != 0)) {
		gtk_render_box(gtkStyle, drawable, state_type, shadow_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;
	}

	int xthickness = OS.gtk_style_get_xthickness(gtkStyle);
	int interior_focus = theme.getWidgetProperty(buttonHandle, "interior-focus");
	if ((style & SWT.DROP_DOWN) != 0) {
		int arrow_width = ARROW_WIDTH;
		int arrow_height = ARROW_HEIGHT;
		int arrow_x = x + width - arrow_width - xthickness - focus_padding;
		if (interior_focus == 0) arrow_x -= focus_line_width;
		int arrow_y = y + (height - arrow_height) / 2;
		byte[] arrow_detail = Converter.wcsToMbcs("arrow", true);
		gtk_render_arrow (gtkStyle, drawable, state_type, OS.GTK_SHADOW_NONE, null, theme.arrowHandle, arrow_detail, OS.GTK_ARROW_DOWN, true, arrow_x, arrow_y, arrow_width, arrow_height);
		if (clientArea != null) {
			clientArea.width -= bounds.x + bounds.width - arrow_x;
		}
	}

    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");

    	if (interior_focus != 0) {
    		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 | DrawData.SELECTED)) != 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);
    }
}

@Override
int hit(Theme theme, Point position, Rectangle bounds) {
	if (!bounds.contains(position)) return DrawData.WIDGET_NOWHERE;
	if ((style & SWT.DROP_DOWN) != 0) {
		long /*int*/ buttonHandle = theme.buttonHandle;
		long /*int*/ gtkStyle = gtk_widget_get_style (buttonHandle);
		int xthickness = OS.gtk_style_get_xthickness(gtkStyle);
		int interior_focus = theme.getWidgetProperty(buttonHandle, "interior-focus");
		int focus_line_width = theme.getWidgetProperty(buttonHandle, "focus-line-width");
		int focus_padding = theme.getWidgetProperty(buttonHandle, "focus-padding");
		int arrow_width = ARROW_WIDTH;
		int arrow_x = bounds.x + bounds.width - arrow_width - xthickness - focus_padding;
		if (interior_focus == 0) arrow_x -= focus_line_width;
		if (arrow_x <= position.x) return DrawData.TOOLITEM_ARROW;
	}
	return DrawData.WIDGET_WHOLE;
}

}
