package com.specmate.uitests.pagemodel;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class UITestUtil {
	/** 
     * If the modal is displayed, we wait 1 second and then check again if the modal is still there
     * The method checks for 10 seconds at intervals of 1 second (driver.findElement TimeOut 
     * (defined by implictlyWait) (1 seconds) * counter (10)) if the modal disappeared
     * 	*/
	public static void waitForModalToDisappear(WebDriver driver) {
		By modalLocator = By.id("loading-modal");
		/*boolean modalDisplayed = true;
    	int counter = 11;
    	
    	driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
    	do {
    		try {
    			counter--;
    			// If modal is not displayed, exception is thrown
    			driver.findElement(modalLocator).isDisplayed();
    			modalDisplayed = counter>0;
    		} catch (NoSuchElementException | StaleElementReferenceException e) {
    			modalDisplayed = false;
    		}
    	} while(modalDisplayed);
    	// Change timeout back to the defined value
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);*/
		try {
			new WebDriverWait(driver, 2).until(
			        ExpectedConditions.visibilityOfElementLocated(modalLocator));
		} catch (TimeoutException te) {
			return;
		}
		new WebDriverWait(driver, 10).until(ExpectedConditions.invisibilityOfElementLocated(modalLocator));
		
	}
	
	
	/**
	 * Checks if the element is present or absent
	 *
	 * @param selector
	 * @return true if the element specified by the selector can be found, false
	 *         otherwise
	 */
	public static boolean isElementPresent(By selector, WebDriver driver) {
		// Set the timeout to 1 second in order to avoid delay
		driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
		boolean returnVal = true;
		try {
			driver.findElement(selector);
		} catch (NoSuchElementException e) {
			returnVal = false;
		} finally {
			// Change timeout back to the defined value
			driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
		}
		return returnVal;
	}
	
	public static void scrollDownTo(By elementLocator, WebDriver driver) {
		JavascriptExecutor js = (JavascriptExecutor) driver;

		// Find element by locator
		WebElement Element = driver.findElement(elementLocator);

		// Scroll the page till the element is found
		js.executeScript("arguments[0].scrollIntoView();", Element);
	}
	
	/** 
     * If the projects are not loaded beforehand, Specmate will display 'Bad Gateway' till they are loaded.
     * This method checks for 30 seconds (driver.findElement TimeOut (defined by implictlyWait) (5 seconds) * counter (6)) if the 
     * loading is finished and refreshes the page each 5 seconds
     * 	*/
    public static void waitForProjectsToLoad(WebDriver driver) {
    	boolean displayed = false;
    	int counter = 5;
    	driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
    	do {
    		try {
    			counter--;
    			displayed = (counter<0) || driver.findElement(By.id("login-username-textfield")).isDisplayed();
    		} catch (NoSuchElementException e) {
    			driver.navigate().refresh();
    		}
    	} while(!displayed);
    	// Change timeout back to the defined value
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
    }
}
@@ -74,16 +74,53 @@
 meUnit;%0D
+%0Aimport java.util.function.Function;%0D
 %0A%0D%0Aimpor
@@ -490,16 +490,112 @@
 tions;%0D%0A
+import org.openqa.selenium.support.ui.FluentWait;%0D%0Aimport org.openqa.selenium.support.ui.Wait;%0D%0A
 import o
@@ -3405,16 +3405,18 @@
 %7B%0D%0A    %09
+/*
 boolean 
@@ -3910,22 +3910,371 @@
 it.SECONDS);
+*/%0D%0A        %0D%0A        %0D%0A    %09Wait%3CWebDriver%3E wait = new FluentWait%3CWebDriver%3E(driver)%0D%0A    %09%09%09.ignoring(NoSuchElementException.class);%0D%0A%0D%0A    %09wait.until(new Function%3CWebDriver, WebElement%3E() %7B%0D%0A    %09%09public WebElement apply(WebDriver driver) %7B%0D%0A    %09%09%09driver.navigate().refresh();%0D%0A    %09%09%09return driver.findElement(By.id(%22foo%22));%0D%0A    %09%09%7D%0D%0A    %09%7D);
 %0D%0A    %7D%0D%0A%7D

Test if fluent wait works