/**
 * 
 */
package pt.quantum.padroes.client.session;


import pt.quantum.padroes.client.services.LoginService;
import pt.quantum.padroes.client.services.LoginServiceAsync;
import pt.quantum.padroes.client.services.SessionTimeoutControlService;
import pt.quantum.padroes.client.services.SessionTimeoutControlServiceAsync;
import pt.quantum.padroes.client.util.Constants;
import pt.quantum.padroes.client.util.LogUtils;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.gwtext.client.widgets.MessageBox;
import com.gwtext.client.widgets.MessageBoxConfig;

/**
 * @author brunolopes
 *
 */
public class SessionTimeOutControl {

	private static final String THE_APP_WILL_CLOSE = " The application will close.";
	private static final int SESSION_WARNING_TIMEOUT_MILLIS = 60000; // 1 minute
	private Timer sessionTimeoutTimer = null;
	private Timer sessionTimeoutResponseTimer = null;

	public static native void closeBrowser() /*-{
	          $wnd.close();
	   }-*/;
	public static native String getQueryString() /*-{
	      return $wnd.location.search.substring(1);
	   }-*/;
	public static native String getContextPath() /*-{
	      return "/" + $wnd.location.pathname.substring(1).substring(0, $wnd.location.pathname.substring(1).indexOf("/"));
	   }-*/;
	
	public SessionTimeOutControl(){
		startUpSessionTimeoutControl();
	}

	public void startUpSessionTimeoutControl()
	{
		
		
		
		SessionTimeoutControlServiceAsync service =  GWT.create(SessionTimeoutControlService.class);
		AsyncCallback<Integer> callback = new AsyncCallback<Integer>()
		{
			public void onSuccess(Integer result)
			{
				int sessionTimeMillis = ((Integer)result).intValue();
				if (sessionTimeMillis == -1)
				{
					displaySessionTimedOut();
				}
				else
				{
					initSessionTimers(sessionTimeMillis);
					buildUI();
				}
			}
			public void onFailure(final Throwable caught)
			{
				MessageBox.show(new MessageBoxConfig()
				{
					{
						setTitle("Error");
						setMsg(caught.toString() + THE_APP_WILL_CLOSE);
						setIconCls(MessageBox.ERROR);
						setButtons(MessageBox.OK);
						setCallback(new MessageBox.PromptCallback()
						{
							public void execute(String btnID, String text)
							{
								closeBrowser();
							}
						});
					}
				});
				
			}
		};
		service.getUserSessionTimeoutMillis(callback);
	}

	private void buildUI()
	{
		// Build the UI.
	}

	/**
	 * Called only once from <b>onModuleLoad</b>.
	 * @sessionTimeInMillis Integer
	 */
	public void initSessionTimers(int sessionTimeMillis)
	{
		// Allow 30 seconds to get the RPC call constructed and called.
		final int x = sessionTimeMillis ;
		//final int x = (sessionTimeMillis - 30000) - SESSION_WARNING_TIMEOUT_MILLIS;
		sessionTimeoutResponseTimer = new Timer()
		{
			public void run(){
				displaySessionTimedOut();
			}
		};

		sessionTimeoutTimer = new Timer(){
			public void run(){
				MessageBox.show(new MessageBoxConfig() {
					{
						setMsg("Your session is about to timeout. Please press \"OK\" to keep working.");
						setIconCls(MessageBox.WARNING);
						setButtons(MessageBox.OK);
						sessionTimeoutResponseTimer.schedule(SESSION_WARNING_TIMEOUT_MILLIS);

						setCallback(new MessageBox.PromptCallback(){
							public void execute(String btnID, String text) {
								// User responded before the response timer elapsed, so keep session by calling the service.
								sessionTimeoutResponseTimer.cancel();
								sessionTimeoutTimer.cancel();
								sessionTimeoutTimer.schedule(x);
								keepUserSessionAlive();
							}
						});
					}
				});
			}
		};
		sessionTimeoutTimer.schedule(x);
	}


	private void keepUserSessionAlive()
	{
		SessionTimeoutControlServiceAsync service = GWT.create(SessionTimeoutControlService.class);
		AsyncCallback<Void> callback = new AsyncCallback<Void>()
		{
			public void onSuccess(Void result){}
			public void onFailure(final Throwable caught)
			{
				MessageBox.show(new MessageBoxConfig()
				{
					{
						setMsg(caught.toString() + THE_APP_WILL_CLOSE);
						setIconCls(MessageBox.ERROR);
						setButtons(MessageBox.OK);
						setCallback(new MessageBox.PromptCallback()
						{
							public void execute(String btnID, String text)
							{
								closeBrowser();
							}
						});
					}
				});
			}
		};
		service.keepUserSessionAlive(callback);
	}

	private void displaySessionTimedOut()
	{
		MessageBox.show(new MessageBoxConfig()
		{
			{
				setMsg("Your session has timed out." + THE_APP_WILL_CLOSE);
				setIconCls(MessageBox.WARNING);
				setButtons(MessageBox.OK);
				Cookies.removeCookie("loggedIn");
				setCallback(new MessageBox.PromptCallback()
				{
					public void execute(String btnID, String text)
					{
						LoginServiceAsync service = GWT.create(LoginService.class);
						service.logout(new AsyncCallback<Void>() {
							@Override
							public void onFailure(Throwable caught) {
								caught.printStackTrace();
								LogUtils.loggingOut();
							}

							@Override
							public void onSuccess(Void result) {
								LogUtils.loggingOut();
							}
						});
					}
				});
			}
		});
	}
}
