// Path: src/main/java/org/robotframework/formslibrary/FormsLibraryException.java
// public class FormsLibraryException extends RuntimeException {
// 
//     private static final long serialVersionUID = 1L;
// 
//     public static final boolean ROBOT_SUPPRESS_NAME = true;
// 
//     public FormsLibraryException(String message) {
//         super(message);
//     }
// 
//     public FormsLibraryException(Throwable t) {
//         super(t);
//     }
// 
//     public FormsLibraryException(String message, Throwable t) {
//         super(message, t);
//     }
// }
// 
// Path: src/main/java/org/robotframework/formslibrary/context/ContextChangeMonitor.java
// public class ContextChangeMonitor {
// 
// 	private List<String> initialOpenLWWindows;
// 
// 	/**
// 	 * Start monitoring for window changes.
// 	 */
// 	public void start() {
// 		if (FormsContext.isFormsServicesApp()) {
// 			initialOpenLWWindows = new LWWindowOperator().getWindowTitles();
// 		} else {
// 
// 		}
// 	}
// 
// 	/**
// 	 * Stop monitoring for window changes and change the context if needed. When
// 	 * a new window is detected, it will be automatically set as the new
// 	 * context. When the current context window was closed, the context will be
// 	 * reset to the root context.
// 	 */
// 	public void stop() {
// 		if (FormsContext.isFormsServicesApp()) {
// 			List<String> newOpenWindows = new LWWindowOperator().getWindowTitles();
// 
// 			// check if a window was closed
// 			if (newOpenWindows.size() < initialOpenLWWindows.size()) {
// 				FormsContext.resetContext();
// 				return;
// 			}
// 
// 			// check for new windows
// 			for (String name : newOpenWindows) {
// 				if (!initialOpenLWWindows.contains(name)) {
// 					// there is a new window open
// 					Logger.info("Found new window '" + name + "', autosetting context to new window.");
// 					new LWWindowOperator().setWindowAsContext(name);
// 					return;
// 				}
// 			}
// 		}
// 
// 	}
// }
// 
// Path: src/main/java/org/robotframework/formslibrary/operator/ButtonOperator.java
// public class ButtonOperator extends AbstractComponentOperator {
// 
// 	/**
// 	 * Initialize a ButtonOperator with the specified button component.
// 	 */
// 	public ButtonOperator(Component component) {
// 		super(component);
// 	}
// 
// 	/**
// 	 * Initialize a ButtonOperator with a button with the specified name in the
// 	 * current context.
// 	 * 
// 	 * @param identifier
// 	 *            button label or ToolTip text.
// 	 */
// 	public ButtonOperator(String identifier) {
// 		super(new ByNameChooser(identifier, ComponentType.ALL_BUTTON_TYPES));
// 	}
// 
// 	/**
// 	 * Simulate a push on the button.
// 	 */
// 	public void push() {
// 		if (!getSource().isEnabled()) {
// 			throw new FormsLibraryException("Button is not enabled.");
// 		}
// 		doPush();
// 		Logger.debug("Button was pushed.");
// 	}
// 
// 	private void doPush() {
// 		if (getSource() instanceof AbstractButton) {
// 			((AbstractButton) getSource()).doClick();
// 		} else {
// 			ObjectUtil.invokeMethod(getSource(), "simulatePush()");
// 		}
// 
// 	}
// 
// 	public void pushAsync() {
// 		if (!getSource().isEnabled()) {
// 			throw new FormsLibraryException("Button is not enabled.");
// 		}
// 		new Thread(() -> doPush()).start();
// 		Logger.debug("Button was pushed.");
// 
// 	}
// 
// }
// 
// Path: src/main/java/org/robotframework/formslibrary/util/Logger.java
// public class Logger {
// 
//     public static void debug(String message) {
//         if (DebugUtil.isDebugEnabled()) {
//             System.out.println("~ " + message);
//         }
//     }
// 
//     public static void info(String message) {
//         System.out.println(message);
//     }
// 
//     public static void error(Throwable t) {
//         t.printStackTrace();
//     }
// }


import org.robotframework.formslibrary.FormsLibraryException;
import org.robotframework.formslibrary.context.ContextChangeMonitor;
import org.robotframework.formslibrary.operator.ButtonOperator;
import org.robotframework.formslibrary.util.Logger;
import org.robotframework.javalib.annotation.ArgumentNames;
import org.robotframework.javalib.annotation.RobotKeyword;
import org.robotframework.javalib.annotation.RobotKeywordOverload;
import org.robotframework.javalib.annotation.RobotKeywords;

package org.robotframework.formslibrary.keyword;


@RobotKeywords
public class ButtonKeywords {

	@RobotKeyword("Uses current context to search for a button by its label and when found, pushes it.\n\n "
			+ " If the button opens a new window and detectWindowChange=true, the context will be set to the new window automatically. "
			+ "Similarly if the button closes a window, the context will be reset to the root context. DetectWindowChange defaults to true. Example:\n | Click Button | _OK_ |\n")
	@ArgumentNames({ "identifier", "detectWindowChange=" })
	public void clickButton(String identifier, boolean detectWindowChange) {

		if (detectWindowChange) {
			ContextChangeMonitor monitor = new ContextChangeMonitor();
			monitor.start();
			new ButtonOperator(identifier).push();

// Path: src/main/java/org/robotframework/formslibrary/FormsLibraryException.java
// public class FormsLibraryException extends RuntimeException {
// 
//     private static final long serialVersionUID = 1L;
// 
//     public static final boolean ROBOT_SUPPRESS_NAME = true;
// 
//     public FormsLibraryException(String message) {
//         super(message);
//     }
// 
//     public FormsLibraryException(Throwable t) {
//         super(t);
//     }
// 
//     public FormsLibraryException(String message, Throwable t) {
//         super(message, t);
//     }
// }
// 
// Path: src/main/java/org/robotframework/formslibrary/context/ContextChangeMonitor.java
// public class ContextChangeMonitor {
// 
// 	private List<String> initialOpenLWWindows;
// 
// 	/**
// 	 * Start monitoring for window changes.
// 	 */
// 	public void start() {
// 		if (FormsContext.isFormsServicesApp()) {
// 			initialOpenLWWindows = new LWWindowOperator().getWindowTitles();
// 		} else {
// 
// 		}
// 	}
// 
// 	/**
// 	 * Stop monitoring for window changes and change the context if needed. When
// 	 * a new window is detected, it will be automatically set as the new
// 	 * context. When the current context window was closed, the context will be
// 	 * reset to the root context.
// 	 */
// 	public void stop() {
// 		if (FormsContext.isFormsServicesApp()) {
// 			List<String> newOpenWindows = new LWWindowOperator().getWindowTitles();
// 
// 			// check if a window was closed
// 			if (newOpenWindows.size() < initialOpenLWWindows.size()) {
// 				FormsContext.resetContext();
// 				return;
// 			}
// 
// 			// check for new windows
// 			for (String name : newOpenWindows) {
// 				if (!initialOpenLWWindows.contains(name)) {
// 					// there is a new window open
// 					Logger.info("Found new window '" + name + "', autosetting context to new window.");
// 					new LWWindowOperator().setWindowAsContext(name);
// 					return;
// 				}
// 			}
// 		}
// 
// 	}
// }
// 
// Path: src/main/java/org/robotframework/formslibrary/operator/ButtonOperator.java
// public class ButtonOperator extends AbstractComponentOperator {
// 
// 	/**
// 	 * Initialize a ButtonOperator with the specified button component.
// 	 */
// 	public ButtonOperator(Component component) {
// 		super(component);
// 	}
// 
// 	/**
// 	 * Initialize a ButtonOperator with a button with the specified name in the
// 	 * current context.
// 	 * 
// 	 * @param identifier
// 	 *            button label or ToolTip text.
// 	 */
// 	public ButtonOperator(String identifier) {
// 		super(new ByNameChooser(identifier, ComponentType.ALL_BUTTON_TYPES));
// 	}
// 
// 	/**
// 	 * Simulate a push on the button.
// 	 */
// 	public void push() {
// 		if (!getSource().isEnabled()) {
// 			throw new FormsLibraryException("Button is not enabled.");
// 		}
// 		doPush();
// 		Logger.debug("Button was pushed.");
// 	}
// 
// 	private void doPush() {
// 		if (getSource() instanceof AbstractButton) {
// 			((AbstractButton) getSource()).doClick();
// 		} else {
// 			ObjectUtil.invokeMethod(getSource(), "simulatePush()");
// 		}
// 
// 	}
// 
// 	public void pushAsync() {
// 		if (!getSource().isEnabled()) {
// 			throw new FormsLibraryException("Button is not enabled.");
// 		}
// 		new Thread(() -> doPush()).start();
// 		Logger.debug("Button was pushed.");
// 
// 	}
// 
// }
// 
// Path: src/main/java/org/robotframework/formslibrary/util/Logger.java
// public class Logger {
// 
//     public static void debug(String message) {
//         if (DebugUtil.isDebugEnabled()) {
//             System.out.println("~ " + message);
//         }
//     }
// 
//     public static void info(String message) {
//         System.out.println(message);
//     }
// 
//     public static void error(Throwable t) {
//         t.printStackTrace();
//     }
// }


// Path: src/main/java/org/robotframework/formslibrary/keyword/ButtonKeywords.java
import org.robotframework.formslibrary.FormsLibraryException;
import org.robotframework.formslibrary.context.ContextChangeMonitor;
import org.robotframework.formslibrary.operator.ButtonOperator;
import org.robotframework.formslibrary.util.Logger;
import org.robotframework.javalib.annotation.ArgumentNames;
import org.robotframework.javalib.annotation.RobotKeyword;
import org.robotframework.javalib.annotation.RobotKeywordOverload;
import org.robotframework.javalib.annotation.RobotKeywords;

package org.robotframework.formslibrary.keyword;


@RobotKeywords
public class ButtonKeywords {

	@RobotKeyword("Uses current context to search for a button by its label and when found, pushes it.\n\n "
			+ " If the button opens a new window and detectWindowChange=true, the context will be set to the new window automatically. "
			+ "Similarly if the button closes a window, the context will be reset to the root context. DetectWindowChange defaults to true. Example:\n | Click Button | _OK_ |\n")
	@ArgumentNames({ "identifier", "detectWindowChange=" })
	public void clickButton(String identifier, boolean detectWindowChange) {

		if (detectWindowChange) {
			ContextChangeMonitor monitor = new ContextChangeMonitor();
			monitor.start();
			new ButtonOperator(identifier).push();

			monitor.stop();
