package hu.pazsitz.pacuse.tests.helpers;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;

/**
 * Waiters.java
 *
 * @author Zoltan Pazsit <pazsitz@pazsitz.hu>
 * @copyright Copyright (c) 2014, Zoltan Pazsit
 */
public class Waiters {
    private static WebDriver webDriver;

    public static void waitForUrl(String inputUrlPart, int seconds) {
        final String ulrPart = inputUrlPart;
        new WebDriverWait(webDriver, seconds).until(new ExpectedCondition<Boolean>() {
            @Override
            public Boolean apply(WebDriver d) {
                return d.getCurrentUrl().contains(ulrPart);
            }
        });
    }

    public static void waitForMultipleUrl(int seconds, String... inputUrlParts) {
        final String[] urlParts = inputUrlParts;
        new WebDriverWait(webDriver, seconds).until(new ExpectedCondition<Boolean>() {
            @Override
            public Boolean apply(WebDriver d) {
                for(String urlPart : urlParts) {
                    if( d.getCurrentUrl().contains(urlPart) ) {
                        return true;
                    }
                }
                return false;
            }
        });
    }

    public static void waitForMultipleUrlOnPayments(int seconds, String... inputUrlParts) {
        final String[] urlParts = inputUrlParts;
        final String startUrl = webDriver.getCurrentUrl();
        new WebDriverWait(webDriver, seconds).until(new ExpectedCondition<Boolean>() {
            @Override
            public Boolean apply(WebDriver d) {
                for(String urlPart : urlParts) {
                    String url = d.getCurrentUrl();
                    try{
                        if(
                            url.contains(urlPart) && !startUrl.equals(url)
                            ||
                            startUrl.equals(url) && d.findElement(By.id("page-level-error")).isDisplayed()
                        ) {
                            return true;
                        }
                    } catch(Exception e) { return false; }
                }
                return false;
            }
        });
    }

    public static void waitForDisplayed(WebElement webElement, int seconds) {
    	final WebElement element = webElement;
    	new WebDriverWait(webDriver, seconds).until(new ExpectedCondition<Boolean>() {
    		@Override
    		public Boolean apply(WebDriver d) {
    			return element.isDisplayed();
    		}
    	});
    }
    
    public static void waitForElementDisappears(By by, int seconds) {
    	waitForElementDisappears(by, seconds, 0);
    }
    
    public static void waitForElementDisappears(By by, int seconds, int startDelay) {
    	webDriver.manage().timeouts().implicitlyWait(startDelay, TimeUnit.SECONDS);
    	final By byStatement = by;
    	new WebDriverWait(webDriver, seconds).until(new ExpectedCondition<Boolean>() {
    		@Override
    		public Boolean apply(WebDriver d) {
    			return d.findElements(byStatement).isEmpty();
    		}
    	});
    }
    
    public static void waitForElementDisplayed(By by, int seconds) {
    	final By byStatement = by;
    	new WebDriverWait(webDriver, seconds).until(new ExpectedCondition<Boolean>() {
    		@Override
    		public Boolean apply(WebDriver d) {
    			return d.findElement(byStatement).isDisplayed();
    		}
    	});
    }
    
    public static void waitForTagNameDisplayed(String inputTag, int seconds) {
    	waitForElementDisplayed(By.tagName(inputTag), seconds);
    }
    
    public static void waitForIdDisplayed(String idName, int seconds) {
    	waitForElementDisplayed(By.id(idName), seconds);
    }

    public static void waitForClassDisplayed(String className, int seconds) {
    	waitForElementDisplayed(By.className(className), seconds);
    }

    public static void waitForDocumentReady(int seconds) {
        new WebDriverWait(webDriver, seconds).until(new ExpectedCondition<Boolean>() {
            @Override
            public Boolean apply(WebDriver driver) {
                return ((JavascriptExecutor)webDriver).executeScript("return document.readyState").equals("complete");
            }
        });
    }

    public static void waitForCondition(ExpectedCondition<Boolean> condition, int seconds) {
        new WebDriverWait(webDriver, seconds).until(condition);
    }

    public static void setWebDriver(WebDriver webDriver) {
        Waiters.webDriver = webDriver;
    }
}

@@ -286,16 +286,74 @@
 dition;%0A
+import org.openqa.selenium.support.ui.ExpectedConditions;%0A
 import o
@@ -583,16 +583,131 @@
 river;%0A%0A
+    /**%0A     * Waits for a match with the given url part%0A     * @param seconds%0A     * @param inputUrlParts%0A     */%0A
     publ
@@ -1055,32 +1055,154 @@
      %7D);%0A    %7D%0A%0A
+    /**%0A     * Waits for a match with any of the given url part%0A     * @param seconds%0A     * @param inputUrlParts%0A     */%0A
     public stati
@@ -1730,967 +1730,8 @@
  %7D%0A%0A
-    public static void waitForMultipleUrlOnPayments(int seconds, String... inputUrlParts) %7B%0A        final String%5B%5D urlParts = inputUrlParts;%0A        final String startUrl = webDriver.getCurrentUrl();%0A        new WebDriverWait(webDriver, seconds).until(new ExpectedCondition%3CBoolean%3E() %7B%0A            @Override%0A            public Boolean apply(WebDriver d) %7B%0A                for(String urlPart : urlParts) %7B%0A                    String url = d.getCurrentUrl();%0A                    try%7B%0A                        if(%0A                            url.contains(urlPart) && !startUrl.equals(url)%0A                            %7C%7C%0A                            startUrl.equals(url) && d.findElement(By.id(%22page-level-error%22)).isDisplayed()%0A                        ) %7B%0A                            return true;%0A                        %7D%0A                    %7D catch(Exception e) %7B return false; %7D%0A                %7D%0A                return false;%0A            %7D%0A        %7D);%0A    %7D%0A%0A
     
@@ -2175,32 +2175,232 @@
  0);%0A    %7D%0A    %0A
+    /**%0A     * Waits for dissapearing of an element,%0A     * uses an initial delay before starts checking the element appearance%0A     * @param by%0A     * @param seconds%0A     * @param startDelay%0A     */%0A
     public stati
@@ -3557,32 +3557,122 @@
 econds);%0A    %7D%0A%0A
+    /**%0A     * Uses javascript check of document.readyState%0A     * @param seconds%0A     */%0A
     public stati
@@ -4017,34 +4017,287 @@
         %7D);%0A    
-%7D%0A
+    waitForCondition(ExpectedConditions.elementToBeClickable(By.id(%22%22)), 10);%0A    %7D%0A%0A    /**%0A     * You can use static methods from ExpectedConditions util class or any ExpectedCondition implementation%0A     * @param condition%0A     * @param seconds%0A     */
 %0A    public stat
@@ -4290,32 +4290,36 @@
    public static
+ %3CT%3E
  void waitForCon
@@ -4343,23 +4343,17 @@
 ndition%3C
-Boolean
+T
 %3E condit
@@ -4434,32 +4434,36 @@
 ndition);%0A    %7D%0A
+    
 %0A    public stat

add comments and use generics on waiter methods