package org.richfaces.testng;

import org.ajax4jsf.template.Template;
import org.richfaces.SeleniumTestBase;
import org.testng.Assert;
import org.testng.annotations.Test;

public class PickListTest extends SeleniumTestBase {

    private static final String PICK_LIST = "pickList";
    private static final String COPY_BTN = "copy";
    private static final String COPY_ALL_BTN = "copyAll";
    private static final String REMOVE_BTN = "remove";
    private static final String REMOVE_ALL_BTN = "removeAll";
    private static final String SRC_ELEM_PREFIX = ":source::";

    @Test
    public void testPickListComponent(Template template) {
        renderPage(template);

        String parentId = getParentId() + "_form:";
        String pickListId = parentId + PICK_LIST;

        String copyElemId = pickListId + COPY_BTN;
        String copyAllElemId = pickListId + COPY_ALL_BTN;
        String removeElemId = pickListId + REMOVE_BTN;
        String removeAllElemId = pickListId + REMOVE_ALL_BTN;

        writeStatus("Check move controls customized labels");

        AssertTextEquals(copyElemId,      "MOVE");
        AssertTextEquals(copyAllElemId,   "MOVE ALL");
        AssertTextEquals(removeElemId,    "TAKE AWAY");
        AssertTextEquals(removeAllElemId, "TAKE ALL AWAY");

        String destListId = parentId + PICK_LIST + "tlTbody";
        String srcListId = parentId + PICK_LIST + "tbody";

        writeStatus("Check initial disposition");

        Assert.assertEquals(getNumberOfChildren(srcListId),  6);
        Assert.assertEquals(getNumberOfChildren(destListId), 2);

        writeStatus("Verify initial selected items.");

        Assert.assertEquals(selenium.getText("xpath=//tbody[@id='" + destListId + "']/tr[1]"), "ZHURIK");
        Assert.assertEquals(selenium.getText("xpath=//tbody[@id='" + destListId + "']/tr[2]"), "MELESHKO");

        writeStatus("Check buttons state");

        assertButtonEnabled(COPY_ALL_BTN);
        assertButtonDisabled(COPY_BTN);
        assertButtonDisabled(REMOVE_BTN);
        assertButtonEnabled(REMOVE_ALL_BTN);

        writeStatus("Try to move the first item and check state thereafter");

        String srcElemPrefix = parentId + PICK_LIST + SRC_ELEM_PREFIX;
        fireMouseEvent(srcElemPrefix + "1", "click", 0, 0, false);
        clickById(copyElemId);

        Assert.assertEquals(getNumberOfChildren(srcListId), 5);
        Assert.assertEquals(getNumberOfChildren(destListId), 3);
        Assert.assertEquals(selenium.getText("xpath=//tbody[@id='" + destListId + "']/tr[3]"), "LEONTIEV");

        writeStatus("Test 'MOVE ALL' button");

        clickById(copyAllElemId);

        Assert.assertEquals(getNumberOfChildren(srcListId), 0);
        Assert.assertEquals(getNumberOfChildren(destListId), 8);

        assertButtonDisabled(COPY_ALL_BTN);
        assertButtonDisabled(COPY_BTN);
        assertButtonDisabled(REMOVE_BTN);
        assertButtonEnabled(REMOVE_ALL_BTN);

        writeStatus("Test 'REMOVE ALL' button");

        clickById(removeAllElemId);

        Assert.assertEquals(getNumberOfChildren(srcListId), 8);
        Assert.assertEquals(getNumberOfChildren(destListId), 0);

        assertButtonEnabled(COPY_ALL_BTN);
        assertButtonDisabled(COPY_BTN);
        assertButtonDisabled(REMOVE_BTN);
        assertButtonDisabled(REMOVE_ALL_BTN);
    }

    private void assertButtonEnabled(String btnId) {
        String id = getParentId() + "_form:" + PICK_LIST;
        Assert.assertTrue(isVisibleById(id + btnId));
        Assert.assertFalse(isVisibleById(id + "dis" + btnId));
    }

    private void assertButtonDisabled(String btnId) {
        String id = getParentId() + "_form:" + PICK_LIST;
        Assert.assertFalse(isVisibleById(id + btnId));
        Assert.assertTrue(isVisibleById(id + "dis" + btnId));
    }

    /**
     * Returns number of children for DOM element with given id.
     * @param elemId DOM element id
     * @return number of children
     */
    private int getNumberOfChildren(String elemId) {
        return selenium.getXpathCount("//*[@id='" + elemId + "']/*").intValue();
    }

    public String getTestUrl() {
        return "pages/pickList/pickListTest.xhtml";
    }

}
