/**
 * License Agreement.
 *
 * JBoss RichFaces - Ajax4jsf Component Library
 *
 * Copyright (C) 2007 Exadel, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */ 
package org.richfaces.testng;

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

public class InputNumberSliderTest extends SeleniumTestBase {

    private static final int BAR_SCALE = 10;

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

        String parentId = getParentId() + "_form:";
        String slider = parentId + "slider";

        String input = slider + "Input";
        String tip = slider + "Tip";
        String track = slider + "Track";

        String ajax = parentId + "ajax";
        String server = parentId + "server";
        String output = parentId + "output";

        writeStatus("Checking initial rendering");
        Assert.assertFalse(isVisibleById(tip));
        checkSliderVisualState(slider, 40);
        AssertTextEquals(output, "40");

        writeStatus("Checking if tip is visible during click");
        selenium.mouseDownAt("id=" + track, "800,1");
        Assert.assertTrue(isVisibleById(tip));
        selenium.mouseUpAt("id=" + track, "800,1");
        Assert.assertFalse(isVisibleById(tip));

        writeStatus("Checking if value is changed with previous click");
        checkSliderVisualState(slider, 80);

        writeStatus("Checking if value is changed with input field");
        selenium.type(input, "22");
        checkSliderVisualState(slider, 22);

        writeStatus("Checking if slider is properly re-rendered and submitted with ajax");
        clickAjaxCommandAndWait(ajax);
        checkSliderVisualState(slider, 32);
        AssertTextEquals(output, "32");

        writeStatus("Checking if slider is properly submitted");
        clickCommandAndWait(server);
        checkSliderVisualState(slider, 42);
        AssertTextEquals(output, "42");

        writeStatus("Checking validation");
        selenium.mouseDownAt("id=" + track, "950,1");
        selenium.mouseUpAt("id=" + track, "950,1");
        clickAjaxCommandAndWait(ajax);
        checkSliderVisualState(slider, 95);
        AssertTextEquals(output, "42");

        selenium.mouseDownAt("id=" + track, "300,1");
        selenium.mouseUpAt("id=" + track, "300,1");
        clickAjaxCommandAndWait(ajax);
        checkSliderVisualState(slider, 40);
        AssertTextEquals(output, "40");
    }

    private void checkSliderVisualState(String id, int value) {
        writeStatus("Checking value in input field");
        AssertValueEquals(id + "Input", Integer.toString(value));
        AssertTextEquals(id + "Tip", Integer.toString(value));

        writeStatus("Checking tip and tracker position");
        String actualHandle = runScript("document.getElementById('" + id + "Handle').style.left");
        String actualTip = runScript("document.getElementById('" + id + "Tip').style.left");

        Assert.assertEquals(actualHandle, actualTip);
        Assert.assertTrue(actualTip.endsWith("px"));

        int actual = new Integer(actualTip.replace("px", "")).intValue();
        int expected = BAR_SCALE * value;
        Assert.assertTrue(Math.abs(actual - expected) <= BAR_SCALE,
                "Handle position is not syncronized with slider value!");
    }

    public String getTestUrl() {
        return "pages/inputNumberSlider/inputNumberSliderTest.xhtml";
    }
}
