package org.richfaces.testng;

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

public class InplaceInputTest extends SeleniumTestBase {

    private static final String INPLACE_INPUT_SIMPLE = "inplaceInput";

    private static final String INPLACE_INPUT_DECORATED = "inplaceInputDecorated";

    private static final String INPLACE_INPUT_DECORATED_OK = "inplaceInputDecoratedok";

    private static final String INPLACE_INPUT_DECORATED_CANCEL = "inplaceInputDecoratedcancel";

    private static final String INPLACE_INPUT_FIELD_POSTFIX = "tempValue";

    private final static String EVENT_TEST_RESULT_FAILED_TEXT = "No";

    private final static String EVENT_TEST_RESULT_PASSED_TEXT = "Passed";

    @Test
    public void testInplaceInputComponentLayout(Template template) {
        renderPage(template);
        writeStatus("Check component layout");

        String inplaceInputS = getParentId() + "_form:" + INPLACE_INPUT_SIMPLE;
        String inplaceInputD = getParentId() + "_form:" + INPLACE_INPUT_DECORATED;

        Assert.assertTrue(isPresentById(inplaceInputS));
        int count = selenium.getXpathCount("//*[@id='" + inplaceInputS + "' and (name()='span' or name()='SPAN')]").intValue();
        Assert.assertTrue(count == 1, "InplaceInput[" + inplaceInputS + "] has layout=inline(default) and should be rendered as 'span' element");

        Assert.assertTrue(isPresentById(inplaceInputD));
        count = selenium.getXpathCount("//*[@id='" + inplaceInputD + "' and (name()='DIV' or name()='div')]").intValue();
        Assert.assertTrue(count == 1, "InplaceInput [" + inplaceInputD + "] has layout=block and should be rendered as 'div' element");
        
    }

    @Test
    public void testInplaceInputClientAPI(Template template) {
        renderPage(template);
        writeStatus("Check component client API");
    }

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

        writeStatus("Check component event triggering");

        String inplaceInputS = getParentId() + "_form:" + INPLACE_INPUT_SIMPLE;
        String inplaceInputD = getParentId() + "_form:" + INPLACE_INPUT_DECORATED;
        String inplaceInputDOk = getParentId() + "_form:" + INPLACE_INPUT_DECORATED_OK;
        String inplaceInputDCancel = getParentId() + "_form:" + INPLACE_INPUT_DECORATED_CANCEL;

        writeStatus("Click first component being tested");

        clickById(inplaceInputS);
        AssertTextEquals(inplaceInputS + "_edit", EVENT_TEST_RESULT_PASSED_TEXT, "oneditactivated event is not fired");

        writeStatus("Stop editing first component being tested");

        String inplaceInputSInput = inplaceInputS + INPLACE_INPUT_FIELD_POSTFIX;
        selenium.fireEvent(inplaceInputSInput, "blur");

        AssertTextEquals(inplaceInputS + "_view", EVENT_TEST_RESULT_PASSED_TEXT, "onviewactivated event is not fired");

        writeStatus("Double-click second component being tested");

        selenium.doubleClick(inplaceInputD);
        AssertTextEquals(inplaceInputD + "_edit", EVENT_TEST_RESULT_PASSED_TEXT, "oneditactivated event is not fired");
        type(inplaceInputSInput, "Hello");

        writeStatus("Stop editing second component being tested");

        selenium.mouseDown(inplaceInputDOk);

        AssertTextEquals(inplaceInputD + "_view", EVENT_TEST_RESULT_PASSED_TEXT, "onviewactivated event is not fired");
    }

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

        String inplaceInputS = getParentId() + "_form:" + INPLACE_INPUT_SIMPLE;
        String inplaceInputD = getParentId() + "_form:" + INPLACE_INPUT_DECORATED;

        String inplaceInputSInput = inplaceInputS + INPLACE_INPUT_FIELD_POSTFIX;
        String inplaceInputDInput = inplaceInputD + INPLACE_INPUT_FIELD_POSTFIX;

        writeStatus("Check component's key attributes");

        writeStatus("test 'editEvent' attribute");

        writeStatus("The first component must change your state by single clicking only");
        clickById(inplaceInputS);
        AssertVisible(inplaceInputSInput);

        writeStatus("The second component must change your state by double clicking only");
        selenium.doubleClick(inplaceInputD);
        AssertVisible(inplaceInputDInput);
    }

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

        String inplaceInputD = getParentId() + "_form:" + INPLACE_INPUT_DECORATED;
        String inplaceInputDInput = inplaceInputD + INPLACE_INPUT_FIELD_POSTFIX;
        String inplaceInputDOk = getParentId() + "_form:" + INPLACE_INPUT_DECORATED_OK;
        String inplaceInputDCancel = getParentId() + "_form:" + INPLACE_INPUT_DECORATED_CANCEL;

        writeStatus("Check component's core functionality");

        writeStatus("Double-click the second component and type an initial text");
        selenium.doubleClick(inplaceInputD);
        type(inplaceInputDInput, "Sun");

        writeStatus("Stop editing with ok. The input has to be saved");
        selenium.mouseDown(inplaceInputDOk);
        String sun = invokeFromComponent(inplaceInputD, "getValue", null);
        Assert.assertEquals(sun, "Sun", "An inputted text has not been saved with ok");
        //AssertTextEquals(inplaceInputD, "Sun", "An inputted text has not been saved with ok");

        writeStatus("Double-click the second component again and type a new text");
        selenium.doubleClick(inplaceInputD);
        type(inplaceInputDInput, "Moon");

        writeStatus("Stop editing with cancel. The input has not to be saved");
        selenium.mouseDown(inplaceInputDCancel);

        sun = invokeFromComponent(inplaceInputD, "getValue", null);
        Assert.assertEquals(sun, "Sun", "An inputted text has not to be saved with cancel");
        //AssertTextEquals(inplaceInputD, "Sun", "An inputted text has not to be saved with cancel");

    }

    @Override
    public String getTestUrl() {
        return "pages/inplaceInput/inplaceInputTest.xhtml";
    }
}
