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

import com.google.gwt.cell.client.EditTextCell.ViewData;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.InputElement;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;

/**
 * Tests for {@link EditTextCell}.
 */
public class EditTextCellTest extends EditableCellTestBase<String, ViewData> {

  public void testEdit() {
    EditTextCell cell = createCell();
    Element parent = Document.get().createDivElement();
    parent.setInnerHTML("<input type='text' value='editing'></input>");
    ViewData viewData = new ViewData("originalValue");
    viewData.setText("newValue");
    cell.setViewData(DEFAULT_KEY, viewData);
    cell.edit(parent, "originalValue", DEFAULT_KEY);

    // Verify the input element.
    Element child = parent.getFirstChildElement();
    assertTrue(InputElement.is(child));
    InputElement input = child.cast();
    assertEquals("newValue", input.getValue());
  }

  /**
   * Cancel and switch to read only mode.
   */
  public void testOnBrowserEventCancel() {
    NativeEvent event = Document.get().createKeyUpEvent(
        false, false, false, false, KeyCodes.KEY_ESCAPE);
    ViewData viewData = new ViewData("originalValue");
    viewData.setText("newValue");
    Element parent = testOnBrowserEvent(
        "<input type='text' value='newValue'></input>", event, "originalValue",
        viewData, null, null);

    // Verify the input element is gone.
    assertEquals("originalValue", parent.getInnerHTML());
  }

  /**
   * Cancel and switch to read only mode after committing once.
   */
  public void testOnBrowserEventCancelSecondEdit() {
    NativeEvent event = Document.get().createKeyUpEvent(
        false, false, false, false, KeyCodes.KEY_ESCAPE);
    ViewData viewData = new ViewData("originalValue");
    viewData.setText("newValue");
    viewData.setEditing(false); // commit.
    viewData.setEditing(true);
    assertEquals("newValue", viewData.getOriginal());
    assertEquals("newValue", viewData.getText());
    viewData.setText("newValue2");
    Element parent = testOnBrowserEvent(
        "<input type='text' value='newValue2'></input>", event, "originalValue",
        viewData, null, viewData);
    assertEquals("newValue", viewData.getOriginal());
    assertEquals("newValue", viewData.getText());
    assertFalse(viewData.isEditing());

    // Verify the input element is gone.
    assertEquals("newValue", parent.getInnerHTML());
  }

  /**
   * Commit and switch to read only mode.
   */
  public void testOnBrowserEventCommit() {
    NativeEvent event = Document.get().createKeyUpEvent(
        false, false, false, false, KeyCodes.KEY_ENTER);
    ViewData viewData = new ViewData("originalValue");
    viewData.setText("newValue");
    assertTrue(viewData.isEditing());
    Element parent = testOnBrowserEvent(
        "<input type='text' value='newValue'></input>", event, "originalValue",
        viewData, "newValue", viewData);
    assertFalse(viewData.isEditing());

    // Verify the input element is gone.
    assertEquals("newValue", parent.getInnerHTML());
  }

  /**
   * Test switching into edit mode from onBrowserEvent.
   */
  public void testOnBrowserEventEdit() {
    NativeEvent event = Document.get().createClickEvent(
        0, 0, 0, 0, 0, false, false, false, false);
    ViewData expectedViewData = new ViewData("editing");
    Element parent = testOnBrowserEvent(
        "helloWorld", event, "editing", null, null, expectedViewData);

    // Verify the input element.
    Element child = parent.getFirstChildElement();
    assertTrue(InputElement.is(child));
    InputElement input = child.cast();
    assertEquals("editing", input.getValue());
  }

  /**
   * Test rendering the cell with a valid value and view data, but without
   * editing.
   */
  public void testRenderViewDataDoneEditing() {
    EditTextCell cell = createCell();
    ViewData viewData = new ViewData("originalValue");
    viewData.setText("newValue");
    viewData.setEditing(false);
    cell.setViewData(DEFAULT_KEY, viewData);
    SafeHtmlBuilder sb = new SafeHtmlBuilder();
    cell.render("originalValue", DEFAULT_KEY, sb);
    assertEquals("newValue", sb.toSafeHtml().asString());
  }

  public void testViewData() {
    // Start in edit mode.
    ViewData viewData = new ViewData("originalValue");
    assertEquals("originalValue", viewData.getOriginal());
    assertEquals("originalValue", viewData.getText());
    assertTrue(viewData.isEditing());
    assertFalse(viewData.isEditingAgain());

    // Change the text.
    viewData.setText("newValue");
    assertEquals("originalValue", viewData.getOriginal());
    assertEquals("newValue", viewData.getText());
    assertTrue(viewData.isEditing());
    assertFalse(viewData.isEditingAgain());

    // Stop editing.
    viewData.setEditing(false);
    assertEquals("originalValue", viewData.getOriginal());
    assertEquals("newValue", viewData.getText());
    assertFalse(viewData.isEditing());
    assertFalse(viewData.isEditingAgain());

    // Edit again.
    viewData.setEditing(true);
    assertEquals("newValue", viewData.getOriginal());
    assertEquals("newValue", viewData.getText());
    assertTrue(viewData.isEditing());
    assertTrue(viewData.isEditingAgain());
  }

  @Override
  protected EditTextCell createCell() {
    return new EditTextCell();
  }

  @Override
  protected String createCellValue() {
    return "helloworld";
  }

  @Override
  protected ViewData createCellViewData() {
    return new ViewData("newValue");
  }

  @Override
  protected boolean dependsOnSelection() {
    return false;
  }

  @Override
  protected String[] getConsumedEvents() {
    return new String[]{"click", "keyup", "keydown", "blur"};
  }

  @Override
  protected String getExpectedInnerHtml() {
    return "helloworld";
  }

  @Override
  protected String getExpectedInnerHtmlNull() {
    return "";
  }

  @Override
  protected String getExpectedInnerHtmlViewData() {
    return "<input type=\"text\" value=\"newValue\" tabindex=\"-1\"></input>";
  }
}
