package me.footlights.demos.good;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

import me.footlights.api.File;
import me.footlights.api.KernelInterface;
import me.footlights.api.WebRequest;
import me.footlights.api.ajax.AjaxHandler;
import me.footlights.api.ajax.Context;
import me.footlights.api.ajax.JavaScript;

import static me.footlights.demos.good.DemoAjaxHandler.AjaxRequest.*;


/** A demonstration of what a {@link Application}'s {@link AjaxHandler} can do. */
class DemoAjaxHandler extends Context
{
	enum AjaxRequest
	{
		INIT,
		TEST_METHODS,
		SYSCALL,
		CONTENT,
		ALL_DONE,
		CLICKED,
		OPEN_FILE,
		LOG,
	}

	DemoAjaxHandler(final KernelInterface kernel, final Logger log)
	{
		register(INIT.name().toLowerCase(), new AjaxHandler()
			{
				@Override public JavaScript service(WebRequest request)
					throws FileNotFoundException, SecurityException, Throwable
				{
					return new JavaScript()
						.append(makeDiv("Initializing well-behaved application."))
						.append(makeDiv("The time is " + new Date()))
						.append(ajax(AjaxRequest.TEST_METHODS.name()));
				}
			});

		register(TEST_METHODS.name(), new AjaxHandler()
		{
			@Override public JavaScript service(WebRequest request)
				throws FileNotFoundException, SecurityException, Throwable
			{
				JavaScript response = new JavaScript();

				response.append(
					makeDiv("Test static method in the Helper class... " + Helper.staticHelp()));

				response.append(makeDiv("Ok, that was fine. Now a constructor... "));
				Helper h = new Helper();

				response.append(makeDiv("And a regular method... "+ h.help()));

				response.append(ajax(AjaxRequest.CONTENT.name()));
				return response;
			}
		});

		register(CONTENT.name(), new AjaxHandler()
		{
			@Override public JavaScript service(WebRequest request)
				throws FileNotFoundException, SecurityException, Throwable
			{
				return new JavaScript()
					.append(makeDiv("loading static JavaScript..."))
					.append("context.load('test.js');")
					.append(ajax(AjaxRequest.SYSCALL.name()))
					;
			}
		});

		register(SYSCALL.name(), new AjaxHandler()
		{
			@Override public JavaScript service(WebRequest request)
				throws FileNotFoundException, SecurityException, Throwable
			{
				JavaScript response = new JavaScript();

				response.append(makeDiv("Finally, do a 'syscall'..."));
				if (kernel == null)
					response.append(makeDiv("but we can't! our kernel reference is null."));
				else
				{
					try
					{
						File file = kernel.save(ByteBuffer.wrap("Hello, world!".getBytes()));
						response.append(makeDiv("saved file: " + file));
					}
					catch (IOException e)
					{
						response.append(makeDiv("Error saving data: " + e));
						log.log(Level.SEVERE, "Error saving data", e);
					}
				}

				response.append(ajax(AjaxRequest.ALL_DONE.name()));
				return response;
			}
		});

		register(ALL_DONE.name(), new AjaxHandler()
		{
			@Override public JavaScript service(WebRequest request)
				throws FileNotFoundException, SecurityException, Throwable
			{
				return new JavaScript().append("context.log('The app works!');");
			}
		});

		register(CLICKED.name().toLowerCase(), new AjaxHandler()
		{
			@Override public JavaScript service(WebRequest request)
				throws FileNotFoundException, SecurityException, Throwable
			{
				return new JavaScript()
					.append("context.log('Clicked \\'" + request.shift().path() + "\\'');");
			}
		});

		register(OPEN_FILE.name().toLowerCase(), new AjaxHandler()
		{
			@Override public JavaScript service(WebRequest request)
				throws FileNotFoundException, SecurityException, Throwable
			{
				File file = kernel.openLocalFile();
				if (file == null)
					return new JavaScript()
						.append("context.log('User cancelled file dialog');");

				return new JavaScript()
					.append(makeDiv("Opened " + file.getInputStream().available() + " B file"));
			}
		});

		register(LOG.name().toLowerCase(), new AjaxHandler()
		{
			@Override public JavaScript service(WebRequest request)
				throws FileNotFoundException, SecurityException, Throwable
			{
				return new JavaScript().append("this is a message to log");
			}
		});
	}


	private static JavaScript makeDiv(String text)
	{
		return new JavaScript()
		.append("context.root.appendElement('div')")
		.append(".appendText('")
		.append(JavaScript.sanitizeText(text))
		.append("')");
	}

	private static JavaScript ajax(String command)
	{
		return new JavaScript()
			.append("context.ajax('")
			.append(JavaScript.sanitizeText(command))
			.append("')");
	}
}

@@ -145,16 +145,38 @@
 l.Date;%0A
+import java.util.Map;%0A
 import j
@@ -233,16 +233,56 @@
 ogger;%0A%0A
+import com.google.common.collect.Maps;%0A%0A
 import m
@@ -3505,103 +3505,371 @@
 %09%09%09%09
-return new JavaScript()%0A%09%09%09%09%09.append(%22context.log('Clicked %5C%5C'%22 + request.shift().path() + %22%5C%5C'
+final String name = request.shift().path();%0A%09%09%09%09int count = clicks.containsKey(name) ? clicks.get(name) + 1 : 1;%0A%09%09%09%09clicks.put(name, count);%0A%09%09%09%09if ((count %25 5) != 1) return new JavaScript();%0A%0A%09%09%09%09return new JavaScript()%0A%09%09%09%09%09.append(%22context.log('Click #%22).appendText(Integer.toString(count))%0A%09%09%09%09%09.appendText(%22 for '%22).appendText(name).appendText(%22'%22).append(%22
 ');%22
@@ -4616,16 +4616,150 @@
 );%0A%09%7D%0A%0A%0A
+%09/** The number of times the user has clicked the 'local' button. */%0A%09private final Map%3CString,Integer%3E clicks = Maps.newHashMap();%0A%0A%0A
 %09private

Use a slightly more complex click handler.