/*
 * Copyright 2008 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.user.client.ui;

import com.google.gwt.dom.client.Element;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.user.client.DOM;

/**
 * Tests the DockPanel widget.
 */
@SuppressWarnings("deprecation")
public class DockPanelTest extends GWTTestCase {

  static class Adder implements HasWidgetsTester.WidgetAdder {
    @Override
    public void addChild(HasWidgets container, Widget child) {
      ((DockPanel) container).add(child, DockPanel.NORTH);
    }
  }

  private static class OnLoadTestLabel extends Label {
    boolean attachedWhenLoaded;

    public OnLoadTestLabel(String text) {
      super(text);
    }

    @Override
    protected void onLoad() {
      // Crawl up the DOM, looking for the body.
      Element curElem = getElement();
      Element body = RootPanel.getBodyElement();
      while (curElem != null) {
        if (curElem == body) {
          attachedWhenLoaded = true;
        }
        curElem = DOM.getParent(curElem);
      }
    }
  }

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

  public void testAddRemove() {
    final DockPanel dock = new DockPanel();

    OnLoadTestLabel l0 = new OnLoadTestLabel("l0");
    OnLoadTestLabel l1 = new OnLoadTestLabel("l1");
    OnLoadTestLabel l2 = new OnLoadTestLabel("l2");
    OnLoadTestLabel l3 = new OnLoadTestLabel("l3");
    OnLoadTestLabel l4 = new OnLoadTestLabel("l4");
    OnLoadTestLabel l5 = new OnLoadTestLabel("l5");

    dock.add(l0, DockPanel.NORTH);
    dock.add(l1, DockPanel.NORTH);
    dock.add(l2, DockPanel.WEST);

    // Add the dock halfway through to make sure onLoad is called for its
    // children correctly in both cases.
    RootPanel.get().add(dock);
    dock.add(l3, DockPanel.EAST);
    dock.add(l5, DockPanel.CENTER);
    dock.add(l4, DockPanel.SOUTH);

    // Ensure that the CENTER element can be added only once.
    try {
      dock.add(new Label("garbage"), DockPanel.CENTER);
      fail("Expecting IllegalArgumentException (from adding CENTER twice)");
    } catch (IllegalArgumentException e) {
    }

    // Test the structure.
    Element table = dock.getElement();
    Element tbody = DOM.getFirstChild(table);

    assertEquals(4, DOM.getChildCount(tbody));

    Element tr0 = DOM.getChild(tbody, 0);
    Element tr1 = DOM.getChild(tbody, 1);
    Element tr2 = DOM.getChild(tbody, 2);
    Element tr3 = DOM.getChild(tbody, 3);

    assertEquals(1, DOM.getChildCount(tr0));
    assertEquals(1, DOM.getChildCount(tr1));
    assertEquals(3, DOM.getChildCount(tr2));
    assertEquals(1, DOM.getChildCount(tr3));

    assertTrue(l0.attachedWhenLoaded);
    assertTrue(l1.attachedWhenLoaded);
    assertTrue(l2.attachedWhenLoaded);
    assertTrue(l3.attachedWhenLoaded);
    assertTrue(l4.attachedWhenLoaded);
    assertTrue(l5.attachedWhenLoaded);

    // Ensure that adding an existing child again moves it to the new slot.
    // (move l4 from SOUTH to NORTH)
    dock.add(l4, DockPanel.NORTH);
    assertTrue(((DockPanel.LayoutData) l4.getLayoutData()).direction == DockPanel.NORTH);
  }

  public void testAddAsIsWidget() {
    DockPanel panel = createDockPanel();
    Widget widget = new Label("foo");
    
    panel.add(widget, DockPanel.NORTH);
    
    assertLogicalPaternity(panel,widget);
    assertPhysicalPaternity(panel,widget);
  }
  
  public void testAttachDetachOrder() {
    HasWidgetsTester.testAll(new DockPanel(), new Adder(), true);
  }

  public void testDebugId() {
    DockPanel dock = new DockPanel();
    Label north1 = new Label("n1");
    dock.add(north1, DockPanel.NORTH);
    Label north2 = new Label("n2");
    dock.add(north2, DockPanel.NORTH);
    Label south1 = new Label("s1");
    dock.add(south1, DockPanel.SOUTH);
    Label south2 = new Label("s2");
    dock.add(south2, DockPanel.SOUTH);
    Label east1 = new Label("e1");
    dock.add(east1, DockPanel.EAST);
    Label east2 = new Label("e2");
    dock.add(east2, DockPanel.EAST);
    Label west1 = new Label("w1");
    dock.add(west1, DockPanel.WEST);
    Label west2 = new Label("w2");
    dock.add(west2, DockPanel.WEST);
    Label center = new Label("c");
    dock.add(center, DockPanel.CENTER);
    dock.ensureDebugId("myDock");

    // Check the body ids
    UIObjectTest.assertDebugId("myDock", dock.getElement());
    UIObjectTest.assertDebugId("myDock-north1",
        DOM.getParent(north1.getElement()));
    UIObjectTest.assertDebugId("myDock-north2",
        DOM.getParent(north2.getElement()));
    UIObjectTest.assertDebugId("myDock-south1",
        DOM.getParent(south1.getElement()));
    UIObjectTest.assertDebugId("myDock-south2",
        DOM.getParent(south2.getElement()));
    UIObjectTest.assertDebugId("myDock-east1",
        DOM.getParent(east1.getElement()));
    UIObjectTest.assertDebugId("myDock-east2",
        DOM.getParent(east2.getElement()));
    UIObjectTest.assertDebugId("myDock-west1",
        DOM.getParent(west1.getElement()));
    UIObjectTest.assertDebugId("myDock-west2",
        DOM.getParent(west2.getElement()));
    UIObjectTest.assertDebugId("myDock-center",
        DOM.getParent(center.getElement()));
  }

  /**
   * Asserts that <b>panel</b> is the logical parent of <b>expectedChild</b>.
   * 
   * @param panel the parent panel
   * @param expectedChild the expected child of <b>panel</b>
   */
  private void assertLogicalPaternity(DockPanel panel, Widget expectedChild) {
    assertSame("The parent and the panel must be the same", panel,
        expectedChild.getParent());
    assertTrue("The child must be in the childen collection of the panel",
        panel.getChildren().contains(expectedChild));
  }
  
  /**
   * Asserts that <b>expectedChild</b> is the first physical child of
   * <b>parent</b>.
   * 
   * @param parent the parent panel
   * @param expectedChild the expected child of <b>panel</b>
   */
  private void assertPhysicalPaternity(Widget parent,
      Widget expectedChild) {
    Element panelElement = parent.getElement();
    Element childElement = expectedChild.getElement();
    assertTrue("The parent's Element of the child must be the panel's Element", 
        panelElement.isOrHasChild(childElement));
  }

  private DockPanel createDockPanel() {
    return new DockPanel();
  }
}
