package ru.yandex.autotests.direct.web.util;

import java.util.List;

import com.thoughtworks.selenium.webdriven.JavascriptLibrary;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Point;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.events.EventFiringWebDriver;

import ru.yandex.autotests.direct.web.steps.UserSteps;
import ru.yandex.qatools.allure.webdriver.rules.WebDriverConfiguration;

import static java.lang.String.format;

/**
 * User: buhter
 * Date: 10.01.13
 * Time: 14:57
 * Class for all JS stuff
 */
public class JavaScriptActions {
    public JavaScriptActions(WebDriverConfiguration config) {
        this.config = config;
        javascriptLibrary = new JavascriptLibrary();
    }

    private WebDriverConfiguration config;
    private final JavascriptLibrary javascriptLibrary;

    /**
     * Метод, вызывающий событие для элемента
     *
     * @param webElement элемент, для которого вызывается событие
     * @param event      событие, вызываемое для элемента
     */
    public void fireEvent(WebElement webElement, String event) {
        javascriptLibrary.callEmbeddedSelenium(config.getDriver(), "triggerEvent", webElement, event);
    }

    /**
     * Метод, вызывающий событие "change" для элемента
     *
     * @param webElement элемент, для которого вызывается событие
     */
    public void fireChangeEvent(WebElement webElement) {
        fireEvent(webElement, "change");
    }

    /**
     * Метод, вызывающий событие "blur" для элемента
     *
     * @param webElement элемент, для которого вызывается событие
     */
    public void fireBlurEvent(WebElement webElement) {
        fireEvent(webElement, "blur");
    }

    public void fireFocusEvent(WebElement webElement) {
        fireEvent(webElement, "focus");
    }

    public void fireKeyUpEvent(WebElement webElement) {
        fireEvent(webElement, "keyup");
    }

    /*
     Хак который отключает часть ф-ий неподдерживаемых в старых браузерах
     */
    public void bemHTML5Hack(String elementName) {
        javascriptLibrary.executeScript(config.getDriver(), format("$('.%s').bem('%s').delMod('html5');", elementName,
                elementName));
    }

    public void fakeAuthoriseAs(String login) {
        String js = "(function () {\n" +
                "    var fl = '%s'.replace(/\\s+/g,'');\n" +
                "    if (fl == '%'+'s') {\n" +
                "        fl = '" + login + "';\n" +
                "    }\n" +
                "\n" +
                "    if (fl != \"\") {\n" +
                "        document.cookie = \"fake_name=\" + escape(fl) + \";\";\n" +
                "    } else {\n" +
                "        document.cookie = \"fake_name=;\";\n" +
                "    }" +
                "    document.location.reload();\n" +
                "}) ()";
        ((JavascriptExecutor) config.getDriver()).executeScript(js);
    }

    public void scrollToBottomOfPage() {
        ((JavascriptExecutor) config.getDriver()).executeScript("window.scrollTo(0, document.body.scrollHeight)");
    }

    // Корректно работает с целыми значениями, в том числе отрицательными
    public void scrollByLines(String numberOfLines) {
        ((JavascriptExecutor) config.getDriver()).executeScript("window.scrollByLines(" + numberOfLines + ")");
    }

    public void scrollToElement(WebElement element) {
        ((JavascriptExecutor) config.getDriver()).executeScript("arguments[0].scrollIntoView();", element);
    }

    public void scrollUpFromPoint(Point point, int stringsUp) {
        ((JavascriptExecutor) config.getDriver()).executeScript(
                "window.scrollBy("+
                        String.valueOf(point.getX()) +
                        "," +
                        String.valueOf(point.getY() + stringsUp) +
                        ")");
    }

    public void hideElements(List<WebElement> elements) {
        ((EventFiringWebDriver) config.getDriver()).executeScript(
                "var elements = arguments[0];" +
                        "for (var i = 0; i < elements.length; i++) {" +
                        "    elements[i].style.display = \"none\";" +
                        "}", elements);
    }

}
