package com.ftinc.si.assist.test.web;

import java.util.ArrayList;
import java.util.HashMap;

import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;

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

import com.ftinc.si.assist.run.Messages;
import com.ftinc.si.assist.test.Tool;

public class Click extends PageAction {

	@Override
	protected void doCore(WebDriver drv, WebElement elm) {
		if (elm != null) {
			Object t_counts = arg_map.get("count"); //$NON-NLS-1$
			Integer i = 1;
			if (t_counts != null) {
				i = Integer.valueOf(t_counts.toString());
			}
			waitUntil1stClick(drv, elm);
			for (int j = 1; j < i; j++) {
				elm.click();
			}
		} else {
			String target = getXpath();
			if (arg_map.containsKey("itemID")) {
				target += " itemID=" + arg_map.get("itemID").toString();
			}
			throw new NotFoundException(this.getClass().getSimpleName() + " " + Messages.getString("Click.1") + target); //$NON-NLS-1$
		}
	}


	//clickやsendkeysで隠れていたために見えない場合のwait。
	private void waitUntil1stClick(final WebDriver drv, final WebElement elm) {
		int t_sec = getTimeout();
		WebDriverWait wait = new WebDriverWait(drv, t_sec);

		final ExpectedCondition<Boolean> t_ec = new ExpectedCondition<Boolean>() {
			public Boolean apply(WebDriver drv) {
				try {
					elm.click();
				} catch (Throwable e) {
					return false;
				}
				return true;
			}
		};
		wait.until(t_ec);
	}

	//javascriptによる強制クリック。※しかし、要素のクリックイベントを強制発火するものではなさそう。上に何かがある時、うまく動かない。
/*
	private void forceClick(WebDriver drv,WebElement elm) {
		final String xscript = "var _evt=document.createEvent(\"MouseEvents\");_evt.initEvent(\"click\",false,true);arguments[0].dispatchEvent(_evt);";
		try {
			final JavascriptExecutor jsexe = (JavascriptExecutor)drv;
			jsexe.executeScript(xscript, elm);
		} catch (Exception e) {
			//そのままスルー
			e.printStackTrace();
		}

	}*/

	//Clickの場合、パラメータ欄はクリック数。
	protected ArrayList<String> getLabelAndParams() {
		ArrayList<String> t_list2 = new ArrayList<String>();
		t_list2.add(Messages.getString("Click.0")); //$NON-NLS-1$
		Object t_counts = arg_map.get("count"); //$NON-NLS-1$
		if (t_counts != null) {
			t_list2.add(t_counts.toString());
		} else {
			t_list2.add("1");
		}
		return t_list2;
	}


	//このPageActionが対象とするXPathの配列を返す
	protected String[] getFocussingXPaths(String xpath) {
		if (xpath != null && xpath.length() > 0) {
			if (xpath.startsWith("input")) { //$NON-NLS-1$
				xpath = "//" + xpath;

				String[] t_list;
				if (!xpath.contains("@type")) {
					t_list = new String[4];
					t_list[0] = xpath + "[@type='button']"; //$NON-NLS-1$ //$NON-NLS-2$
					t_list[1] = xpath + "[@type='submit']"; //$NON-NLS-1$ //$NON-NLS-2$
					t_list[2] = xpath + "[@type='reset']"; //$NON-NLS-1$ //$NON-NLS-2$
					t_list[3] = xpath + "[@type='image']"; //$NON-NLS-1$ //$NON-NLS-2$
				} else {
					t_list = new String[] {xpath};
				}
				return t_list;
			}
			return super.getFocussingXPaths(xpath);
		}
		return new String[] {"//input[@type='button']", "//input[@type='submit']", "//input[@type='reset']", "//input[@type='image']"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
	}

	//PageActionEditorの第二列に書き込む内容を合成する。
	@SuppressWarnings("unchecked")
	protected String getJsonElement(String target, String arg) {
		if (target != null && arg != null) {
			//targetからMapを作り、countを加えて、Json化した方が安全。
			arg_map = (HashMap<String, Object>)Tool.getObjectfromJSON(HashMap.class, "{" + target + "}"); //$NON-NLS-1$ //$NON-NLS-2$
			arg_map.put("count", arg); //$NON-NLS-1$
		}

		return super.getJsonElement(null, null);
	}


	//WebElementGetterから呼ばれる。
	protected JPopupMenu getPopup(WebElementGetter wg, String cur_str) {
		if (hasPath()) {
			JPopupMenu t_pop = new JPopupMenu();
			t_pop.add(new JMenuItem(new InsertAction("\"id\":\"\"", "AddID", wg, cur_str))); //$NON-NLS-1$ //$NON-NLS-2$
			t_pop.add(new JMenuItem(new InsertAction("\"xpath\":\"//*[@id='']\"", "AddXpath", wg, cur_str))); //$NON-NLS-1$ //$NON-NLS-2$

			JMenu t_menu = new JMenu(Messages.getString("Click.4")); //$NON-NLS-1$

			if (cur_str.matches("(^[\\s\\S]*::|^)input[\\s\\S]*$")) { //$NON-NLS-1$
				//inputタグを含んでいる
				t_menu.add(new JMenuItem(new InsertAction(Messages.getString("Click.14"), "EqualsText@", wg, cur_str))); //$NON-NLS-1$ //$NON-NLS-2$
				t_menu.add(new JMenuItem(new InsertAction(Messages.getString("Click.13"), "ContainsText@", wg, cur_str))); //$NON-NLS-1$ //$NON-NLS-2$
			} else {
				t_menu.add(new JMenuItem(new InsertAction(Messages.getString("Click.12"), "EqualsText", wg, cur_str))); //$NON-NLS-1$ //$NON-NLS-2$
				t_menu.add(new JMenuItem(new InsertAction(Messages.getString("Click.11"), "ContainsText", wg, cur_str))); //$NON-NLS-1$ //$NON-NLS-2$
				t_menu.add(new JMenuItem(new InsertAction(Messages.getString("Click.10"), "HasTag", wg, cur_str))); //$NON-NLS-1$ //$NON-NLS-2$
			}
			t_pop.add(t_menu);
			return t_pop;
		}
		return null;
	}
}
