package de.reinhardt_karlheinz.pcc.android;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
import android.widget.Button;
import android.widget.Toast;
import de.reinhardt_karlheinz.pcc.android.servers.USBServer;
import de.reinhardt_karlheinz.pcc.events.PCCMessageEvent;
import de.reinhardt_karlheinz.pcc.events.PCConnectionEvent;
import de.reinhardt_karlheinz.pcc.interfaces.PCCConnection;
import de.reinhardt_karlheinz.pcc.listeners.PCCMsgListener;
import de.reinhardt_karlheinz.pcc.listeners.PCConnectionListener;

/**
 * 
 * (c) Copyright 2012, Karlheinz Reinhardt. All rights reserved.<br>
 * 
 * TODO USE WAIT and NOTIFY instead of synchronized
 * 
 * @author Karlheinz Reinhardt
 * @version 0.0.0.1
 */
public class PCControlActivity extends Activity implements
		PCConnectionListener, PCCMsgListener {
	PCCConnection svr;

	static final String LOG_TAG = "TEST";

	//
	// private ArrayList<HashMap<String, String>> services;
	//
	// private ArrayList<String> categories;

	// private PCCPluginInterface_android service = null;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		Toast.makeText(getBaseContext(), "App started", 10000).show();
		Log.i("TEST", "App started");
		svr = new USBServer(38001);
		svr.addPCConnectionListener(PCControlActivity.this);
		svr.addPCCMsgListener(PCControlActivity.this);
		detectPlugins();
		listPlugins();
		startMinecraftActivity();
		// loadPlugins();

		// for (PCCPluginConnection pl : pluginConn) {
		// try {
		// pl.getPlugin().onPluginStart();
		// } catch (RemoteException e) {
		// // TODO Auto-generated catch block
		// e.printStackTrace();
		// }
		// }
		// Android_PluginManager plgmngr = new Android_PluginManager(svr,
		// getPackageManager());
		// try {
		// Log.i("TEST", "loading plugins");
		// plgmngr.loadPlugins();
		// Log.i("TEST", "plugin loaded");
		// } catch (FileNotFoundException e1) {
		// // TODO Auto-generated catch block
		// e1.printStackTrace();
		// } catch (IOException e1) {
		// // TODO Auto-generated catch block
		// e1.printStackTrace();
		// } catch (ClassNotFoundException e1) {
		// // TODO Auto-generated catch block
		// e1.printStackTrace();
		// } catch (InstantiationException e1) {
		// // TODO Auto-generated catch block
		// e1.printStackTrace();
		// } catch (IllegalAccessException e1) {
		// // TODO Auto-generated catch block
		// e1.printStackTrace();
		// }
		try {
			svr.startServer();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void startMinecraftActivity() {
		TouchVector ref = new TouchVector(0, 0, 0, 1);
		TouchVector v = new TouchVector(0, 1, 0, 1);
		Log.d(LOG_TAG, "angle");
//		Intent mc = new Intent(this, Minecraft.class);
//		startActivity(mc);
		finish();
	}

	private void showToastInUiThread(final String msg, final int lenght) {
		this.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				Toast.makeText(getBaseContext(), msg, lenght).show();
			}
		});
	}

	public static final String ACTION_PICK_PLUGIN = "pcc.intent.action.PICK_PLUGIN";

	ArrayList<HashMap<String, String>> services;

	public void detectPlugins() {
		services = new ArrayList<HashMap<String, String>>();
		PackageManager packageManager = getPackageManager();
		Intent baseIntent = new Intent(ACTION_PICK_PLUGIN);
		List<ResolveInfo> service_list = packageManager.queryIntentServices(
				baseIntent, PackageManager.GET_RESOLVED_FILTER);

		for (ResolveInfo ri : service_list) {
			Log.d(LOG_TAG, ri.toString());
			ServiceInfo sinfo = ri.serviceInfo;
			ApplicationInfo ai = sinfo.applicationInfo;
			IntentFilter filter = ri.filter;
			Log.d(LOG_TAG, sinfo.packageName);
			if (filter != null) {
				HashMap<String, String> item = new HashMap<String, String>();
				Iterator<String> categories = filter.categoriesIterator();
				while (categories.hasNext()) {
					String cat = categories.next();
					Log.d(LOG_TAG, cat);
					if (cat.startsWith("pcc.intent.category.")) {
						// service is a valid pcc plugin
						item.put("categ", cat);
						item.put("pkg", ai.packageName);
						item.put("svname", sinfo.name);
						services.add(item);
					}
				}
			}
		}
	}

	public void listPlugins() {
		Log.d(LOG_TAG, "### listing plugins ###");
		for (HashMap<String, String> item : services) {
			Log.d(LOG_TAG, item.get("categ"));
			Log.d(LOG_TAG, item.get("pkg"));
			Log.d(LOG_TAG, item.get("svname"));
		}
		Log.d(LOG_TAG, "### END PLUGINS ###");
	}

	// /**
	// * interfaces
	// *
	// */
	// private ArrayList<IPCCPlugin> plService = new ArrayList<IPCCPlugin>();

	/**
	 * Class for interacting with the main interface of the service.
	 */
	// private ArrayList<ServiceConnection> service_connections = new
	// ArrayList<ServiceConnection>();

	// private ServiceConnection svconn = null;
	private ArrayList<PCCPluginConnection> pluginConn = new ArrayList<PCCPluginConnection>();

	public void loadPlugins() {
		// // for (IPCCPlugin plugin : plService) {
		// for (int i = 0; i < services.size(); i++) {
		// svconn = new ServiceConnection() {
		//
		// @Override
		// public void onServiceConnected(ComponentName name, IBinder service) {
		// // TODO Auto-generated method stub
		// plService.add(IPCCPlugin.Stub.asInterface(service));
		// Log.d(LOG_TAG, "onServiceConnected");
		// }
		//
		// @Override
		// public void onServiceDisconnected(ComponentName name) {
		// plService = null;// TODO
		// Log.d(LOG_TAG, "onServiceDisconnected");
		// }
		//
		// };
		// Intent intnt = new Intent(ACTION_PICK_PLUGIN);
		// intnt.addCategory(services.get(i).get("categ"));
		// bindService(intnt, svconn, Context.BIND_AUTO_CREATE);
		// Log.d(LOG_TAG, services.get(i).get("categ"));
		// Log.d(LOG_TAG, services.get(i).get("pkg"));
		// Log.d(LOG_TAG, services.get(i).get("svname"));
		// try {
		// plService.get(i).onPluginStart();
		// } catch (RemoteException e) {
		// // TODO Auto-generated catch block
		// e.printStackTrace();
		// }
		// }
		// PCCPluginConnection pccPlConn;
		for (HashMap<String, String> item : services) {
			Log.i("TEST", "iterate");
			PCCPluginConnection pccPlConn = new PCCPluginConnection();
			Intent i = new Intent(ACTION_PICK_PLUGIN);
			i.addCategory(item.get("categ"));
			bindService(i, pccPlConn, Context.BIND_AUTO_CREATE);
			pluginConn.add(pccPlConn);
		}
	}

	@Override
	public void onPCConnectionEstablished(PCConnectionEvent e) {
		showToastInUiThread("Connection to PC opend", Toast.LENGTH_SHORT);
		Log.i("TEST", "Connection to PC opend");
	}

	@Override
	public void onPCConnectionLost(PCConnectionEvent e) {
		// showToastInUiThread("Connection to PC lost", Toast.LENGTH_SHORT);
		Log.i("TEST", "Connection to PC lost");
		// TODO do not close intent
		this.finish();
	}

	@Override
	public void onMsgReceived(PCCMessageEvent e) {
		// TODO change
		showToastInUiThread("msg: " + e.getMessage(), Toast.LENGTH_SHORT);
		Log.i("TEST", "msgw: " + e.getMessage());
		// for (IPCCPlugin plg : plService) {
		// try {
		// plg.onMessageReceived(e.getMessage());
		// } catch (RemoteException e1) {
		// // TODO Auto-generated catch block
		// e1.printStackTrace();
		// }
		// }
	}

	@Override
	public void onCommandReceived(PCCMessageEvent e) {
		// TODO change
		showToastInUiThread("cmd: " + e.getMessage(), Toast.LENGTH_SHORT);
		Log.i("TEST", "cmd: " + e.getMessage());
	}

}