/*
   Copyright 2013 Harri Smatt

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */

package fi.harism.lucidchat;

import java.util.List;

import android.app.Activity;
import android.app.Dialog;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import fi.harism.lucidchat.api.Channel;
import fi.harism.lucidchat.api.ChatHandler;
import fi.harism.lucidchat.api.Conversation;
import fi.harism.lucidchat.api.Message;
import fi.harism.lucidchat.api.User;

/**
 * Main activity class - the one and only.
 */
public class MainActivity extends Activity implements ContainerCenter.Observer,
		ContainerMenu.Observer, ChatHandler.Observer {

	private ChatHandler mChatHandler = new ChatHandler();
	private ContainerCenter mContainerCenter;
	private ContainerMenu mContainerMenu;
	private PreferencesHandler mPreferences;
	private Conversation mPreviousConversation;
	private String mUserId, mUserAuth, mSessionId;

	@Override
	public boolean dispatchKeyEvent(KeyEvent event) {
		if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
			if (mContainerCenter.getX() > 0) {
				mContainerCenter.setMenuVisible(false);
				return true;
			}
			finish();
		}
		return super.dispatchKeyEvent(event);
	}

	@Override
	public void onConversationAdded(final Conversation conversation) {
		runOnUiThread(new Runnable() {
			@Override
			public void run() {
				if (conversation.getType() == Conversation.TYPE_CHANNEL) {
					Message message = new Message(Message.TYPE_LOG, getString(
							R.string.channel_joined, conversation.getTitle()));
					conversation.addMessage(message);
				}
				mContainerMenu.setConversation(conversation);
				mContainerMenu
						.setConversations(mChatHandler.getConversations());
				mContainerCenter.setConversation(conversation);
				mContainerCenter.setMenuVisible(false);
			}
		});
	}

	@Override
	public void onConversationRemoved(final Conversation conversation) {
		runOnUiThread(new Runnable() {
			@Override
			public void run() {
				mContainerMenu.removeConversation(conversation);
				if (mContainerCenter.getConversation() == conversation) {
					mContainerCenter.setConversation(mChatHandler
							.getServerLog());
					mContainerMenu.setConversation(mChatHandler.getServerLog());
				}
			}
		});
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setSoftInputMode(
				WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED);

		setContentView(R.layout.layout_main);

		mPreferences = new PreferencesHandler(this);

		mContainerCenter = (ContainerCenter) findViewById(R.id.container_center);
		mContainerMenu = (ContainerMenu) findViewById(R.id.container_menu);

		mContainerCenter.setMenuContainer(mContainerMenu);
		mContainerCenter.setCenterObserver(this);
		mContainerMenu.setMenuObserver(this);
		mChatHandler.addObserver(this);

		showDialogConnect();
		mContainerCenter.setConversation(mChatHandler.getServerLog());
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		mChatHandler.disconnect();
	}

	@Override
	public void onInfoJoin(Conversation conversation, String userId, String name) {
		Message message = new Message(Message.TYPE_LOG, getString(
				R.string.channel_join, name));
		conversation.addMessage(message);
	}

	@Override
	public void onInfoPart(Conversation conversation, String userId, String name) {
		Message message = new Message(Message.TYPE_LOG, getString(
				R.string.channel_part, name));
		conversation.addMessage(message);
	}

	@Override
	public void onJoinChannel(Channel channel) {
		if (mChatHandler.hasConversation(channel)) {
			Conversation conversation = mChatHandler.getConversation(channel);
			mContainerMenu.setConversation(conversation);
			mContainerCenter.setConversation(conversation);
			mContainerCenter.setMenuVisible(false);
		} else {
			mChatHandler.joinChannel(channel.getId());
		}
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.menu_about: {
			showDialogAbout();
			return true;
		}
		case R.id.menu_serverlog: {
			mContainerMenu.setConversation(mChatHandler.getServerLog());
			mContainerCenter.setConversation(mChatHandler.getServerLog());
			mContainerCenter.setMenuVisible(false);
			return true;
		}
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	public void onPartConversation(Conversation conversation) {
		mChatHandler.removeConversation(conversation);
	}

	@Override
	public void onSearch(String searchText) {
		mChatHandler.search(searchText);
	}

	@Override
	public void onSearchResults(final List<Channel> channels,
			final List<User> users) {
		runOnUiThread(new Runnable() {
			@Override
			public void run() {
				mContainerMenu.addSearchResults(users, channels);
			}
		});
	}

	@Override
	public boolean onSendMessage(Conversation conversation, String text) {
		return mChatHandler.sendMessage(conversation, text);
	}

	@Override
	public void onServerConnect(String userId, String userAuth, String sessionId) {
		mUserId = userId;
		mUserAuth = userAuth;
		mSessionId = sessionId;

		runOnUiThread(new Runnable() {
			@Override
			public void run() {
				if (mPreviousConversation != null) {
					mContainerCenter.setConversation(mPreviousConversation);
					mContainerMenu.setConversation(mPreviousConversation);
					mPreviousConversation = null;
				}
			}
		});
	}

	@Override
	public void onServerDisconnect() {
		if (isFinishing()) {
			return;
		}
		runOnUiThread(new Runnable() {
			@Override
			public void run() {
				mPreviousConversation = mContainerCenter.getConversation();
				mContainerCenter.setMenuVisible(false);
				mContainerCenter.setConversation(mChatHandler.getServerLog());
				mContainerMenu.setConversation(mChatHandler.getServerLog());
				if (mUserId != null && mUserAuth != null && mSessionId != null) {
					showDialogReconnect();
				} else {
					showDialogConnect();
				}
			}
		});
	}

	@Override
	public void onShowConversation(Conversation conversation) {
		mContainerMenu.setConversation(conversation);
		mContainerCenter.setConversation(conversation);
		mContainerCenter.setMenuVisible(false);
	}

	@Override
	public void onStartConversation(User user) {
		if (mChatHandler.hasConversation(user)) {
			Conversation conversation = mChatHandler.getConversation(user);
			mContainerMenu.setConversation(conversation);
			mContainerCenter.setConversation(conversation);
			mContainerCenter.setMenuVisible(false);
		} else {
			mChatHandler.addConversation(user);
		}
	}

	/**
	 * Show about dialog.
	 */
	private void showDialogAbout() {
		final Dialog dlg = new Dialog(this);
		dlg.requestWindowFeature(Window.FEATURE_NO_TITLE);
		dlg.setContentView(R.layout.dialog_about);
		dlg.findViewById(R.id.button_close).setOnClickListener(
				new View.OnClickListener() {
					@Override
					public void onClick(View v) {
						dlg.dismiss();
					}
				});
		dlg.show();
	}

	/**
	 * Show connect dialog.
	 */
	private void showDialogConnect() {
		DialogConnect dlg = new DialogConnect(this,
				new DialogConnect.DialogObserver() {
					@Override
					public void onCancel(DialogConnect dialog) {
						dialog.dismiss();
						finish();
					}

					@Override
					public void onConnect(DialogConnect dialog) {
						mPreferences.setName(dialog.getName());
						mPreferences.setRealName(dialog.getRealName());
						mPreferences.setAutojoin(dialog.getAutojoin());
						mPreferences.save();

						mChatHandler.connect(dialog.getName(),
								dialog.getRealName(), dialog.getAutojoin());
						dialog.dismiss();
					}
				});
		dlg.setName(mPreferences.getName());
		dlg.setRealName(mPreferences.getRealName());
		dlg.setAutojoin(mPreferences.getAutojoin());
		dlg.show();
	}

	/**
	 * Show reconnect dialog.
	 */
	private void showDialogReconnect() {
		final Dialog dlg = new Dialog(this);
		dlg.requestWindowFeature(Window.FEATURE_NO_TITLE);
		dlg.setContentView(R.layout.dialog_reconnect);
		dlg.findViewById(R.id.button_cancel).setOnClickListener(
				new View.OnClickListener() {
					@Override
					public void onClick(View v) {
						dlg.dismiss();
						finish();
					}
				});
		dlg.findViewById(R.id.button_connect).setOnClickListener(
				new View.OnClickListener() {
					@Override
					public void onClick(View v) {
						dlg.dismiss();
						mChatHandler.reconnect(mUserId, mUserAuth, mSessionId);
					}
				});
		dlg.show();
	}

}
