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

import java.util.Locale;

/**
 * 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", 0, aPixel);
    int bPixel = clampArrayGet.get(-9999);
    assertEquals("CanvasPixelArray should return 0 for values off its end", 0, bPixel);
  }

  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(Locale.ROOT));
    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());
  }
}
