/*
* This file is part of the Remote Sensor Actuator Interface (ReSAI).
*
* Copyright(c) Andreas Kipp, Frederic Siepmann
* http://opensource.cit-ec.de/projects/resai
*
* This file may be licensed under the terms of of the
* GNU Lesser General Public License Version 3 (the ``LGPL''),
* or (at your option) any later version.
*
* Software distributed under the License is distributed
* on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the LGPL for the specific language
* governing rights and limitations.
*
* You should have received a copy of the LGPL along with this
* program. If not, go to http://www.gnu.org/licenses/lgpl.html
* or write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The development of this software was supported by the
* Excellence Cluster EXC 277 Cognitive Interaction Technology.
* The Excellence Cluster EXC 277 is a grant of the Deutsche
* Forschungsgemeinschaft (DFG) in the context of the German
* Excellence Initiative.
*
*/

/**
 * Template for a new tab.
 *
 * @author akipp
 */

package de.unibi.airobots.resaidroid.tabactivities.template;

import java.util.HashMap;

import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;

import android.app.Activity;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import de.unibi.airobots.resaidroid.TabComponentMap;
import de.unibi.airobots.resaidroid.communication.Communicator;
import de.unibi.airobots.resaidroid.communication.XmppConnection;
import de.unibi.airobots.resaidroid.constants.Constants.Commands;
import de.unibi.airobots.resaidroid.constants.Constants.Properties;
import de.unibi.airobots.resaidroid.constants.ReturnCodes;
import de.unibi.airobots.resaidroid.constants.ServerConfig;
import de.unibi.airobots.resaidroid.helper.EasyDialog;

public abstract class TabTemplate extends Activity implements
		TabTemplateInterface {

	protected String TAG = "<NO TAG SET>";
	protected final Handler messageHandler = new Handler();
	protected Message mIn;
	protected Message mOut;
	protected TabComponentMap cm;
	protected PacketListener packetListener;
	protected HashMap<String, String> receivedProperties = new HashMap<String, String>();
	protected String componentName;
	protected HashMap<String, String> propertiesToSend = new HashMap<String, String>();
	protected Communicator com;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		TAG = this.getClass().getSimpleName();
		com = new XmppConnection();
		com.setUsingActivity(this);
		Resources res = getResources();
		cm = new TabComponentMap(res);
		componentName = cm.getComponent(TAG);
	}

	@Override
	protected void onPause() {
		super.onPause();
		removePacketHandler();

		addProperty(Properties.CMD.name(), Commands.disconnectComponent.name());
		addProperty(Properties.COMP.name(), cm.getComponent(TAG));
		// TODO auslagern?
		propertiesToSend.put("TAG", "ComponentDispatcher");
		sendMessage(ServerConfig.RECIPIENT_FULL);

		// Log.i(TAG, "########TAG " + TAG + " pausing...");

	}

	@Override
	protected void onResume() {
		super.onResume();

		createPacketHandler();

		addProperty(Properties.CMD.name(), Commands.requestComponent.name());
		addProperty(Properties.COMP.name(), componentName);
		// TODO outsource?
		propertiesToSend.put("TAG", "ComponentDispatcher");
		sendMessage(ServerConfig.RECIPIENT_FULL);
	}

	@Override
	public void onBackPressed() {
		removePacketHandler();

		addProperty("TAG", "ReSAIServerThread");
		addProperty(Properties.CMD.name(), Commands.disconnect.name());
		sendMessage(ServerConfig.RECIPIENT_FULL);

		returnWithError(ReturnCodes.BACK_PRESSED);
	}

	public void createPacketHandler() {
		if (com.isLoggedIn()) {
			packetListener = new MyPacketListener();
			PacketFilter filter = new PacketTypeFilter(Message.class);
			XmppConnection.addListener(packetListener, filter);
		}
	}

	public void removePacketHandler() {
		if (com.isConnected() && com.isLoggedIn()) {
			com.removeListener(packetListener);
		}
	}

	public void returnWithError(int errorCode) {
		if (getParent() != null) {
			getParent().setResult(errorCode);
		} else {
			setResult(errorCode);
		}

		if (com.isConnected()) {
			com.disconnect();
		}
		finish();
	}

	/**
	 * Add item to list of properties to send.
	 * 
	 * @param prop
	 *            qualifier
	 * @param value
	 */
	public synchronized void addProperty(String prop, String value) {
		propertiesToSend.put(prop, value);
	}

	/**
	 * Send a message to the given recipient.
	 * 
	 * @param recipient
	 */
	public synchronized void sendMessage(String recipient) {

		com.sendMessage(recipient, propertiesToSend);

		propertiesToSend.clear();
	}

	protected void showError(final String error) {
		messageHandler.post(new Runnable() {
			public void run() {
				EasyDialog.makeToast(getParent(), "ERROR RECEIVED\n" + error);
			}
		});
	}

	/**
	 * Private class for implementing own PacketListener. Only processes
	 * messages for a given TAG.
	 * 
	 * @author akipp
	 * 
	 */
	private class MyPacketListener implements PacketListener {
		public void processPacket(Packet packet) {

			if (packet instanceof Message) {

				mIn = (Message) packet;

				//TODO hack for scripterthread
				if (mIn.getPropertyNames().contains("TAG")
						&& (mIn.getProperty("TAG").equals(cm.getComponent(TAG)) || ((mIn
								.getProperty("TAG") + "_2").equals(cm
								.getComponent(TAG))))) {

					synchronized (receivedProperties) {
						receivedProperties.clear();
						for (String prop : mIn.getPropertyNames()) {
							receivedProperties.put(prop, mIn.getProperty(prop)
									.toString());
						}
						processProperties();
					}
				}

				if (mIn.getPropertyNames().contains("MESSAGE_TYPE")
						&& mIn.getProperty("MESSAGE_TYPE").equals("ERROR")) {
					showError(mIn.getBody());
				}
			}
		}
	}
}