/*
 * Copyright 2010 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.canvas.dom.client;

import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.canvas.dom.client.Context2d.Composite;
import com.google.gwt.canvas.dom.client.Context2d.LineCap;
import com.google.gwt.canvas.dom.client.Context2d.LineJoin;
import com.google.gwt.canvas.dom.client.Context2d.TextAlign;
import com.google.gwt.canvas.dom.client.Context2d.TextBaseline;
import com.google.gwt.junit.DoNotRunWith;
import com.google.gwt.junit.Platform;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.user.client.ui.RootPanel;

/**
 * Tests {@link Context2d}.
 * 
 * Because HtmlUnit does not support HTML5, you will need to run these tests manually in order to
 * have them run. To do that, go to "run configurations" or "debug configurations", select the test
 * you would like to run, and put this line in the VM args under the arguments tab:
 * -Dgwt.args="-runStyle Manual:1"
 */
@DoNotRunWith(Platform.HtmlUnitUnknown)
public class Context2dTest extends GWTTestCase {
  protected Canvas canvas1;
  protected Canvas canvas2;

  native boolean isGecko190OrBefore() /*-{
    return @com.google.gwt.dom.client.DOMImplMozilla::isGecko190OrBefore()();
  }-*/;

  native boolean isWebkit525OrBefore() /*-{
    return @com.google.gwt.dom.client.DOMImplWebkit::isWebkit525OrBefore()();
  }-*/;

  @Override
  public String getModuleName() {
    return "com.google.gwt.canvas.Canvas";
  }

  @Override
  protected void gwtSetUp() throws Exception {
    canvas1 = Canvas.createIfSupported();
    canvas2 = Canvas.createIfSupported();

    if (canvas1 == null) {
      return; // don't continue if not supported
    }

    RootPanel.get().add(canvas1);
    RootPanel.get().add(canvas2);
  }

  @Override
  protected void gwtTearDown() throws Exception {
    RootPanel.get().remove(canvas1);
    RootPanel.get().remove(canvas2);
  }

  public void testArc() {
    if (canvas1 == null) {
      return; // don't continue if not supported
    }

    canvas1.setHeight("40px");
    canvas1.setWidth("60px");
    canvas1.setCoordinateSpaceHeight(80);
    canvas1.setCoordinateSpaceWidth(120);

    // get a 2d context
    Context2d context = canvas1.getContext2d();

    // make sure there are no issues drawing an arc
    try {
      context.beginPath();
      context.arc(50, 50, 40, 0, Math.PI);
      context.closePath();
      context.stroke();
    } catch (Exception e) {
      fail("Should not throw an exception drawing an arc: " + e.getMessage());
    }
  }

  public void testFillRect() {
    if (canvas1 == null) {
      return; // don't continue if not supported
    }

    // Safari 3.0 does not support getImageData(), so the following tests are disabled for
    // Safari 3.0 and before.
    if (isWebkit525OrBefore()) {
      return;
    }

    canvas1.setHeight("40px");
    canvas1.setWidth("60px");
    canvas1.setCoordinateSpaceHeight(80);
    canvas1.setCoordinateSpaceWidth(120);
    assertEquals(40, canvas1.getOffsetHeight());
    assertEquals(60, canvas1.getOffsetWidth());
    assertEquals(80, canvas1.getCoordinateSpaceHeight());
    assertEquals(120, canvas1.getCoordinateSpaceWidth());

    // get a 2d context
    Context2d context = canvas1.getContext2d();

    // draw green rectangle filling 1st half of canvas
    context.setFillStyle(CssColor.make("#00fF00"));
    context.fillRect(0, 0, 60, 80);
    // draw red rectangle filling 2nd half of canvas
    context.setFillStyle("#fF0000");
    context.fillRect(60, 0, 60, 80);

    // test that the first pixel is green and the last pixel is red
    ImageData imageData = context.getImageData(0, 0, 120, 80);
    CanvasPixelArray pixelArray = imageData.getData();
    assertEquals(000, pixelArray.get(0));
    assertEquals(255, pixelArray.get(1));
    assertEquals(000, pixelArray.get(2));
    assertEquals(255, pixelArray.get(3));
    assertEquals(255, pixelArray.get((40 * 20 - 1) * 4 + 0));
    assertEquals(000, pixelArray.get((40 * 20 - 1) * 4 + 1));
    assertEquals(000, pixelArray.get((40 * 20 - 1) * 4 + 2));
    assertEquals(255, pixelArray.get((40 * 20 - 1) * 4 + 3));
    
    // draw a blue square in the top left
    context.setFillStyle("#0000fF");
    context.fillRect(0, 0, 20, 20);
    imageData = context.getImageData(0, 0, 20, 20);
    pixelArray = imageData.getData();
    
    // test that the first pixel is blue
    assertEquals(000, pixelArray.get(0));
    assertEquals(000, pixelArray.get(1));
    assertEquals(255, pixelArray.get(2));
    assertEquals(255, pixelArray.get(3));
  }

  public void testFillStyle() {
    if (canvas1 == null) {
      return; // don't continue if not supported
    }

    // get the 2d contexts
    Context2d context1 = canvas1.getContext2d();
    Context2d context2 = canvas2.getContext2d();

    // test that a color can be set and is correct
    context1.setFillStyle(CssColor.make("#ffff00"));
    FillStrokeStyle fillStyleCol = context1.getFillStyle();
    assertTrue("fillStyleCol is a color", fillStyleCol.getType() == FillStrokeStyle.TYPE_CSSCOLOR);
    assertFalse("fillStyleCol is a color", fillStyleCol.getType() == FillStrokeStyle.TYPE_GRADIENT);
    assertFalse("fillStyleCol is a color", fillStyleCol.getType() == FillStrokeStyle.TYPE_PATTERN);

    // test that a gradient can be set and is correct
    CanvasGradient gradient = context1.createLinearGradient(0, 0, 10, 20);
    gradient.addColorStop(0.5f, "#ffaaff");
    context1.setFillStyle(gradient);
    FillStrokeStyle fillStyleGrad = context1.getFillStyle();
    assertFalse("fillStyleGrad is a gradient", fillStyleGrad.getType() == FillStrokeStyle.TYPE_CSSCOLOR);
    assertTrue("fillStyleGrad is a gradient", fillStyleGrad.getType() == FillStrokeStyle.TYPE_GRADIENT);
    assertFalse("fillStyleGrad is a gradient", fillStyleGrad.getType() == FillStrokeStyle.TYPE_PATTERN);

    // test that a pattern can be set and is correct
    CanvasPattern pattern = context1.createPattern(canvas1.getCanvasElement(), 
        Context2d.Repetition.REPEAT);
    context1.setFillStyle(pattern);
    FillStrokeStyle fillStylePat = context1.getFillStyle();
    assertFalse("fillStylePat is a pattern", fillStylePat.getType() == FillStrokeStyle.TYPE_CSSCOLOR);
    assertFalse("fillStylePat is a pattern", fillStylePat.getType() == FillStrokeStyle.TYPE_GRADIENT);
    assertTrue("fillStylePat is a pattern", fillStylePat.getType() == FillStrokeStyle.TYPE_PATTERN);
    
    // test that a StrokeStyle can be passed around w/o knowing what it is
    FillStrokeStyle fillStyle = context1.getFillStyle();
    context2.setFillStyle(fillStyle);
    FillStrokeStyle fillStyle2 = context2.getFillStyle();
    assertFalse("fillStyle2 is a pattern", fillStyle2.getType() == FillStrokeStyle.TYPE_CSSCOLOR);
    assertFalse("fillStyle2 is a pattern", fillStyle2.getType() == FillStrokeStyle.TYPE_GRADIENT);
    assertTrue("fillStyle2 is a pattern", fillStyle2.getType() == FillStrokeStyle.TYPE_PATTERN);
  }

  public void testFont() {
    if (canvas1 == null) {
      return; // don't continue if not supported
    }

    Context2d context = canvas1.getContext2d();
    context.setFont("40px \"Times New Roman\"");
    assertEquals("40px \"Times New Roman\"", context.getFont());
  }

  public void testGlobalAlpha() {
    if (canvas1 == null) {
      return; // don't continue if not supported
    }

    Context2d context = canvas1.getContext2d();
    context.setGlobalAlpha(0.5);
    assertEquals(0.5, context.getGlobalAlpha());
  }

  // This test currently fails on IE9 and is disabled.
  public void disabled_testGlobalComposite() {
    if (canvas1 == null) {
      return; // don't continue if not supported
    }

    Context2d context = canvas1.getContext2d();
    context.setGlobalCompositeOperation(Composite.SOURCE_OVER);
    assertEquals(Composite.SOURCE_OVER.getValue(), context.getGlobalCompositeOperation());
    context.setGlobalCompositeOperation(Composite.DESTINATION_OVER);
    assertEquals(Composite.DESTINATION_OVER.getValue(), context.getGlobalCompositeOperation());
  }

  public void testGradient() {
    if (canvas1 == null) {
      return; // don't continue if not supported
    }

    // Safari 3.0 does not support getImageData(), so the following tests are disabled for
    // Safari 3.0 and before.
    if (isWebkit525OrBefore()) {
      return;
    }

    canvas1.setHeight("40px");
    canvas1.setWidth("60px");
    canvas1.setCoordinateSpaceHeight(40);
    canvas1.setCoordinateSpaceWidth(60);
    Context2d context = canvas1.getContext2d();

    // fill the canvas with black
    context.setFillStyle("#000000");
    context.fillRect(0, 0, 60, 40);
    
    // create a linear gradient from the top-left to the bottom-right.
    CanvasGradient linearGradient = context.createLinearGradient(0, 0, 60, 40);
    linearGradient.addColorStop(0, "#ff0000");
    linearGradient.addColorStop(1, "#00ffff");
    context.setFillStyle(linearGradient);
    context.fillRect(0, 0, 60, 40);
    
    // test that the first pixel is ff0000, the last is 000fff, and the middle is something else
    // isn't exact due to rounding, give 5px approx wiggle-room
    int approx = 5;
    ImageData imageData = context.getImageData(0, 0, 60, 40);
    CanvasPixelArray pixelArray = imageData.getData();

    assertTrue(255 - pixelArray.get(0) < approx);
    assertTrue(pixelArray.get(1) - 000 < approx);
    assertTrue(pixelArray.get(2) - 000 < approx);
    assertTrue(255 - pixelArray.get(3) < approx);
    assertFalse(000 == pixelArray.get((60 * 40 / 2) * 4 + 0));
    assertFalse(255 == pixelArray.get((60 * 40 / 2) * 4 + 0));
    assertTrue(pixelArray.get((60 * 40 - 1) * 4 + 0) - 000 < approx);
    assertTrue(255 - pixelArray.get((60 * 40 - 1) * 4 + 1) < approx);
    assertTrue(255 - pixelArray.get((60 * 40 - 1) * 4 + 2) < approx);
    assertTrue(255 - pixelArray.get((60 * 40 - 1) * 4 + 3) < approx);
  }

  public void testImageData() {
    if (canvas1 == null) {
      return; // don't continue if not supported
    }
    
    // Firefox 3.0 does not support createImageData(), so the following tests are disabled
    // for FF 3.0 and before.
    if (isGecko190OrBefore()) {
      return;
    }

    // Safari 3.0 does not support getImageData(), so the following tests are disabled for
    // Safari 3.0 and before.
    if (isWebkit525OrBefore()) {
      return;
    }

    canvas1.setHeight("40px");
    canvas1.setWidth("60px");
    canvas1.setCoordinateSpaceHeight(40);
    canvas1.setCoordinateSpaceWidth(60);
    Context2d context = canvas1.getContext2d();

    // fill the canvas with ffff00
    context.setFillStyle("#ffff00");
    context.fillRect(0, 0, 60, 40);
    
    // create a 1 x 1 image
    ImageData onePx = context.createImageData(1, 1); // will fail on FF3.0 (not such method)
    assertEquals(1, onePx.getHeight());
    assertEquals(1, onePx.getWidth());
    
    // set the image to a single blue pixel
    CanvasPixelArray onePxArray = onePx.getData();
    onePxArray.set(0, 000);
    onePxArray.set(1, 000);
    onePxArray.set(2, 255);
    onePxArray.set(3, 255);
    
    // put the pixel at location 10, 10 on the canvas
    context.putImageData(onePx, 10, 10);
    ImageData verifyPx = context.getImageData(10, 10, 1, 1);
    assertEquals(1, verifyPx.getWidth());
    assertEquals(1, verifyPx.getHeight());
    CanvasPixelArray verifyPxArray = verifyPx.getData();
    assertEquals(onePxArray.get(0), verifyPxArray.get(0));
    assertEquals(onePxArray.get(1), verifyPxArray.get(1));
    assertEquals(onePxArray.get(2), verifyPxArray.get(2));
    assertEquals(onePxArray.get(3), verifyPxArray.get(3));

    // test that edge cases don't blow up: values outside the range 0...255
    ImageData clampPixels = context.createImageData(3, 3); // will fail on FF3.0 (not such method)
    CanvasPixelArray clampArraySet = clampPixels.getData();
    try {
      clampArraySet.set(2, -2);
      clampArraySet.set(3, 270);
      context.putImageData(clampPixels, 4, 4);
    } catch (Exception e) {
      fail("Should not throw exception when setting values outside the range of 0...255");
    }
    clampPixels = context.getImageData(4, 4, 3, 3);
    CanvasPixelArray clampArrayGet = clampPixels.getData();
    
    // test that edge cases don't blow up: fall off the CanvasPixelArray end
    int aPixel = clampArrayGet.get(9999);
    assertEquals("CanvasPixelArray should return 0 for values off its end", aPixel, 0);
    int bPixel = clampArrayGet.get(-9999);
    assertEquals("CanvasPixelArray should return 0 for values off its end", bPixel, 0);
  }

  public void testIsPointInPath() {
    if (canvas1 == null) {
      return; // don't continue if not supported
    }

    canvas1.setHeight("40px");
    canvas1.setWidth("60px");
    canvas1.setCoordinateSpaceHeight(40);
    canvas1.setCoordinateSpaceWidth(60);

    Context2d context = canvas1.getContext2d();
    context.beginPath();
    context.moveTo(10, 10);
    context.lineTo(20, 20);
    context.lineTo(20, 10);
    context.closePath();
    
    assertTrue("Point should be in path", context.isPointInPath(18, 12));
    assertFalse("Point should not be in path", context.isPointInPath(1, 1));
  }

  public void testLines() {
    if (canvas1 == null) {
      return; // don't continue if not supported
    }

    canvas1.setHeight("40px");
    canvas1.setWidth("60px");
    canvas1.setCoordinateSpaceHeight(40);
    canvas1.setCoordinateSpaceWidth(60);
    
    Context2d context = canvas1.getContext2d();
    context.setFillStyle("#ff00ff");
    context.setLineCap(LineCap.BUTT);
    context.setLineJoin(LineJoin.BEVEL);
    context.setLineWidth(2);

    context.beginPath();
    context.moveTo(10, 10);
    context.lineTo(20, 20);
    context.lineTo(20, 10);
    context.closePath();

    assertEquals(LineCap.BUTT.getValue(), context.getLineCap());
    assertEquals(LineJoin.BEVEL.getValue(), context.getLineJoin());
    assertEquals(2.0, context.getLineWidth());
  }

  public void testMiter() {
    if (canvas1 == null) {
      return; // don't continue if not supported
    }

    Context2d context = canvas1.getContext2d();
    context.setMiterLimit(3);
    assertEquals(3.0, context.getMiterLimit());
  }

  public void testPixelManipulation() {
    if (canvas1 == null) {
      return; // don't continue if not supported
    }

    // Safari 3.0 does not support getImageData(), so the following tests are disabled for
    // Safari 3.0 and before.
    if (isWebkit525OrBefore()) {
      return;
    }

    canvas1.setHeight("40px");
    canvas1.setWidth("60px");
    canvas1.setCoordinateSpaceHeight(40);
    canvas1.setCoordinateSpaceWidth(60);
    Context2d context = canvas1.getContext2d();

    // fill the canvas with ff0000
    context.setFillStyle("#ff0000");
    context.fillRect(0, 0, 60, 40);
    // fill the 1st and 2nd quadrants with green
    context.setFillStyle("#00ff00");
    context.fillRect(0, 0, 60, 20);
    
    ImageData imageData = context.getImageData(0, 0, 60, 40);
    assertEquals("Pixels in first quadrant should be green", 0, imageData.getRedAt(45, 10));
    assertEquals("Pixels in first quadrant should be green", 255, imageData.getGreenAt(45, 10));
    assertEquals("Pixels in third quadrant should be red", 255, imageData.getRedAt(15, 30));
    assertEquals("Pixels in third quadrant should be red", 0, imageData.getGreenAt(15, 30));
  }

  public void testShadows() {
    if (canvas1 == null) {
      return; // don't continue if not supported
    }
    
    // Firefox 3.0 returns the incorrect shadowBlur value so the following tests are disabled
    // for FF 3.0 and before.
    if (isGecko190OrBefore()) {
      return;
    }

    canvas1.setHeight("40px");
    canvas1.setWidth("60px");
    canvas1.setCoordinateSpaceHeight(40);
    canvas1.setCoordinateSpaceWidth(60);

    Context2d context = canvas1.getContext2d();
    context.setShadowBlur(3);
    context.setShadowColor("#ff00ff");
    context.setShadowOffsetX(3);
    context.setShadowOffsetY(4);
    context.lineTo(60, 40);
    assertEquals(3.0, context.getShadowBlur());
    assertEquals("#ff00ff", context.getShadowColor().toLowerCase());
    assertEquals(3.0, context.getShadowOffsetX());
    assertEquals(4.0, context.getShadowOffsetY());
  }

  public void testStrokeStyle() {
    if (canvas1 == null) {
      return; // don't continue if not supported
    }

    // get the 2d contexts
    Context2d context1 = canvas1.getContext2d();
    Context2d context2 = canvas2.getContext2d();

    // test that a color can be set and is correct
    context1.setStrokeStyle(CssColor.make("#ffff00"));
    FillStrokeStyle strokeStyleCol = context1.getStrokeStyle();
    assertTrue("strokeStyleCol is a color", strokeStyleCol.getType() == FillStrokeStyle.TYPE_CSSCOLOR);
    assertFalse("strokeStyleCol is a color", strokeStyleCol.getType() == FillStrokeStyle.TYPE_GRADIENT);
    assertFalse("strokeStyleCol is a color", strokeStyleCol.getType() == FillStrokeStyle.TYPE_PATTERN);

    // test that a gradient can be set and is correct
    CanvasGradient gradient = context1.createLinearGradient(0, 0, 10, 20);
    gradient.addColorStop(0.5, "#ff000f");
    context1.setStrokeStyle(gradient);
    FillStrokeStyle strokeStyleGrad = context1.getStrokeStyle();
    assertFalse("strokeStyleGrad is a gradient", strokeStyleGrad.getType() == FillStrokeStyle.TYPE_CSSCOLOR);
    assertTrue("strokeStyleGrad is a gradient", strokeStyleGrad.getType() == FillStrokeStyle.TYPE_GRADIENT);
    assertFalse("strokeStyleGrad is a gradient", strokeStyleGrad.getType() == FillStrokeStyle.TYPE_PATTERN);

    // test that a pattern can be set and is correct
    CanvasPattern pattern = context1.createPattern(canvas1.getCanvasElement(), 
        Context2d.Repetition.REPEAT);
    context1.setStrokeStyle(pattern);
    FillStrokeStyle strokeStylePat = context1.getStrokeStyle();
    assertFalse("strokeStylePat is a pattern", strokeStylePat.getType() == FillStrokeStyle.TYPE_CSSCOLOR);
    assertFalse("strokeStylePat is a pattern", strokeStylePat.getType() == FillStrokeStyle.TYPE_GRADIENT);
    assertTrue("strokeStylePat is a pattern", strokeStylePat.getType() == FillStrokeStyle.TYPE_PATTERN);
    
    // test that a StrokeStyle can be passed around w/o knowing what it is
    FillStrokeStyle strokeStyle = context1.getStrokeStyle();
    context2.setStrokeStyle(strokeStyle);
    FillStrokeStyle strokeStyle2 = context2.getStrokeStyle();
    assertFalse("strokeStyle2 is a pattern", strokeStyle2.getType() == FillStrokeStyle.TYPE_CSSCOLOR);
    assertFalse("strokeStyle2 is a pattern", strokeStyle2.getType() == FillStrokeStyle.TYPE_GRADIENT);
    assertTrue("strokeStyle2 is a pattern", strokeStyle2.getType() == FillStrokeStyle.TYPE_PATTERN);
  }

  public void testText() {
    if (canvas1 == null) {
      return; // don't continue if not supported
    }
    
    canvas1.setHeight("40px");
    canvas1.setWidth("60px");
    Context2d context = canvas1.getContext2d();
    context.setFont("bold 40px sans-serif");
    context.setTextAlign(TextAlign.CENTER);
    context.setTextBaseline(TextBaseline.HANGING);
    context.fillText("GWT", 50, 60);
    assertEquals(TextAlign.CENTER.getValue(), context.getTextAlign());
    assertEquals(TextBaseline.HANGING.getValue(), context.getTextBaseline());
  }
}
