/*******************************************************************************
 * Copyright (c) 2012 Original authors 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:
 *     Original authors and others - initial API and implementation
 ******************************************************************************/
package org.eclipse.nebula.widgets.nattable.renderer.swt;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;

/**
 * This class contains utility methods for drawing graphics
 * 
 * @see <a href="http://java-gui.info/Apress-The.Definitive.Guide.to.SWT.and.JFace/8886final/LiB0095.html">GC snippets</a>
 */
public class GraphicsUtils {
	  
  /**
   * Draws text vertically (rotates plus or minus 90 degrees). Uses the current
   * font, color, and background.
   * <dl>
   * <dt><b>Styles: </b></dt>
   * <dd>UP, DOWN</dd>
   * </dl>
   *
   * @param string the text to draw
   * @param x the x coordinate of the top left corner of the drawing rectangle
   * @param y the y coordinate of the top left corner of the drawing rectangle
   * @param gc the GC on which to draw the text
   * @param style the style (SWT.UP or SWT.DOWN)
   *           <p>
   *           Note: Only one of the style UP or DOWN may be specified.
   *           </p>
   */
  public static void drawVerticalText(String string, int x, int y, GC gc, int style) {
	  drawVerticalText(string, x, y, false, false, true, gc, style);
  }
	  
  /**
   * Draws text vertically (rotates plus or minus 90 degrees). Uses the current
   * font, color, and background.
   * <dl>
   * <dt><b>Styles: </b></dt>
   * <dd>UP, DOWN</dd>
   * </dl>
   *
   * @param string the text to draw
   * @param x the x coordinate of the top left corner of the drawing rectangle
   * @param y the y coordinate of the top left corner of the drawing rectangle
   * @param underline set to <code>true</code> to render the text underlined
   * @param strikethrough set to <code>true</code> to render the text strikethrough
   * @param paintBackground set to <code>false</code> to render the background transparent.
   * 			Needed for example to render the background with an image or gradient with another painter
   * 			so the text drawn here should have no background.
   * @param gc the GC on which to draw the text
   * @param style the style (SWT.UP or SWT.DOWN)
   *           <p>
   *           Note: Only one of the style UP or DOWN may be specified.
   *           </p>
   */
  //TODO get style information for underline, strikethrough and paintbackground
  //this should be somehow encapsulated in a more clean way so it is hidden from the interface call in IGraphicsContext
  public static void drawVerticalText(String string, int x, int y, 
		  boolean underline, boolean strikethrough, boolean paintBackground, 
		  GC gc, int style) {
    // Get the current display
    Display display = Display.getCurrent();
    if (display == null) SWT.error(SWT.ERROR_THREAD_INVALID_ACCESS);

    // Determine string's dimensions
//    FontMetrics fm = gc.getFontMetrics();
    Point pt = gc.textExtent(string.trim());

    // Create an image the same size as the string
    Image stringImage = new Image(display, pt.x, pt.y);

    // Create a GC so we can draw the image
    GC stringGc = new GC(stringImage);

    // Set attributes from the original GC to the new GC
    stringGc.setAntialias(gc.getAntialias());
    stringGc.setTextAntialias(gc.getTextAntialias());
    stringGc.setForeground(gc.getForeground());
    stringGc.setBackground(gc.getBackground());
    stringGc.setFont(gc.getFont());

    // Fill the image with the specified background color
    // to avoid white spaces if the text does not fill the 
    // whole image (e.g. on new lines)
    stringGc.fillRectangle(0, 0, pt.x, pt.y);
    
    // Draw the text onto the image
    stringGc.drawText(string, 0, 0);
	
    //draw underline and/or strikethrough
    if (underline || strikethrough) {
		//check and draw underline and strikethrough separately so it is possible to combine both
		if (underline) {
			//y = start y of text + font height 
			// - half of the font descent so the underline is between the baseline and the bottom
			int underlineY = pt.y - (stringGc.getFontMetrics().getDescent() / 2);
			stringGc.drawLine(
					0, 
					underlineY, 
					pt.x, 
					underlineY);
		}
		
		if (strikethrough) {
			//y = start y of text + half of font height + ascent so lower case characters are
			//also strikethrough
			int strikeY = (pt.y / 2) + (stringGc.getFontMetrics().getLeading() / 2);
			stringGc.drawLine(
					0, 
					strikeY, 
					pt.x, 
					strikeY);
		}
	}

    // Draw the image vertically onto the original GC
    drawVerticalImage(stringImage, x, y, paintBackground, gc, style);

    // Dispose the new GC
    stringGc.dispose();

    // Dispose the image
    stringImage.dispose();
  }

  /**
   * Draws an image vertically (rotates plus or minus 90 degrees)
   * <dl>
   * <dt><b>Styles: </b></dt>
   * <dd>UP, DOWN</dd>
   * </dl>
   *
   * @param image the image to draw
   * @param x the x coordinate of the top left corner of the drawing rectangle
   * @param y the y coordinate of the top left corner of the drawing rectangle
   * @param gc the GC on which to draw the image
   * @param style the style (SWT.UP or SWT.DOWN)
   *           <p>
   *           Note: Only one of the style UP or DOWN may be specified.
   *           </p>
   */
  public static void drawVerticalImage(Image image, int x, int y, GC gc, int style) {
	  drawVerticalImage(image, x, y, true, gc, style);
  }

  /**
   * Draws an image vertically (rotates plus or minus 90 degrees)
   * <dl>
   * <dt><b>Styles: </b></dt>
   * <dd>UP, DOWN</dd>
   * </dl>
   *
   * @param image the image to draw
   * @param x the x coordinate of the top left corner of the drawing rectangle
   * @param y the y coordinate of the top left corner of the drawing rectangle
   * @param paintBackground set to <code>false</code> to render the background transparent.
   * 			Needed for example to render the background with an image or gradient with another painter
   * 			so the text drawn here should have no background.
   * @param gc the GC on which to draw the image
   * @param style the style (SWT.UP or SWT.DOWN)
   *           <p>
   *           Note: Only one of the style UP or DOWN may be specified.
   *           </p>
   */
  public static void drawVerticalImage(Image image, int x, int y, boolean paintBackground, GC gc, int style) {
    // Get the current display
    Display display = Display.getCurrent();
    if (display == null) SWT.error(SWT.ERROR_THREAD_INVALID_ACCESS);

    // Use the image's data to create a rotated image's data
    ImageData sd = image.getImageData();
    ImageData dd = new ImageData(sd.height, sd.width, sd.depth, sd.palette);
    dd.transparentPixel = sd.transparentPixel;
    
    //set the defined backgroundcolor to be transparent
    if (!paintBackground) {
    	dd.transparentPixel = sd.palette.getPixel(gc.getBackground().getRGB());
    }

    // Determine which way to rotate, depending on up or down
    boolean up = (style & SWT.UP) == SWT.UP;

    // Run through the horizontal pixels
    for (int sx = 0; sx < sd.width; sx++) {
      // Run through the vertical pixels
      for (int sy = 0; sy < sd.height; sy++) {
        // Determine where to move pixel to in destination image data
        int dx = up ? sy : sd.height - sy - 1;
        int dy = up ? sd.width - sx - 1 : sx;
        // Swap the x, y source data to y, x in the destination
        dd.setPixel(dx, dy, sd.getPixel(sx, sy));
      }
    }

    // Create the vertical image
    Image vertical = new Image(display, dd);

    // Draw the vertical image onto the original GC
    gc.drawImage(vertical, x, y);

    // Dispose the vertical image
    vertical.dispose();
  }

  /**
   * Creates an image containing the specified text, rotated either plus or minus
   * 90 degrees.
   * <dl>
   * <dt><b>Styles: </b></dt>
   * <dd>UP, DOWN</dd>
   * </dl>
   *
   * @param text the text to rotate
   * @param font the font to use
   * @param foreground the color for the text
   * @param background the background color
   * @param style direction to rotate (up or down)
   * @return Image
   *          <p>
   *          Note: Only one of the style UP or DOWN may be specified.
   *          </p>
   */
  public static Image createRotatedText(String text, Font font, Color foreground,
      Color background, int style) {
    // Get the current display
    Display display = Display.getCurrent();
    if (display == null) SWT.error(SWT.ERROR_THREAD_INVALID_ACCESS);

    // Create a GC to calculate font's dimensions
    GC gc = new GC(display);
    gc.setFont(font);

    // Determine string's dimensions
//    FontMetrics fm = gc.getFontMetrics();
    Point pt = gc.textExtent(text);

    // Dispose that gc
    gc.dispose();

    // Create an image the same size as the string
    Image stringImage = new Image(display, pt.x, pt.y);
    // Create a gc for the image
    gc = new GC(stringImage);
    gc.setFont(font);
    gc.setForeground(foreground);
    gc.setBackground(background);

    // Draw the text onto the image
    gc.drawText(text, 0, 0);

    // Draw the image vertically onto the original GC
    Image image = createRotatedImage(stringImage, style);

    // Dispose the new GC
    gc.dispose();

    // Dispose the horizontal image
    stringImage.dispose();

    // Return the rotated image
    return image;
  }

  /**
   * Creates a rotated image (plus or minus 90 degrees)
   * <dl>
   * <dt><b>Styles: </b></dt>
   * <dd>UP, DOWN</dd>
   * </dl>
   *
   * @param image the image to rotate
   * @param style direction to rotate (up or down)
   * @return Image
   *          <p>
   *          Note: Only one of the style UP or DOWN may be specified.
   *          </p>
   */
  public static Image createRotatedImage(Image image, int style) {
    // Get the current display
    Display display = Display.getCurrent();
    if (display == null) SWT.error(SWT.ERROR_THREAD_INVALID_ACCESS);

    // Use the image's data to create a rotated image's data
    ImageData sd = image.getImageData();
    ImageData dd = new ImageData(sd.height, sd.width, sd.depth, sd.palette);

    // Determine which way to rotate, depending on up or down
    boolean up = (style & SWT.UP) == SWT.UP;

    // Run through the horizontal pixels
    for (int sx = 0; sx < sd.width; sx++) {
      // Run through the vertical pixels
      for (int sy = 0; sy < sd.height; sy++) {
        // Determine where to move pixel to in destination image data
        int dx = up ? sy : sd.height - sy - 1;
        int dy = up ? sd.width - sx - 1 : sx;

        // Swap the x, y source data to y, x in the destination
        dd.setPixel(dx, dy, sd.getPixel(sx, sy));
      }
    }

    // Create the vertical image
    return new Image(display, dd);
  }
  
}

