/* 
 * Copyright 2012 by AVM GmbH <info@avm.de>
 *
 * This software contains free software; you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License ("License") as 
 * published by the Free Software Foundation  (version 3 of the License). 
 * This software is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the copy of the 
 * License you received along with this software for more details.
 */

package de.avm.android.fritzapp.gui;

import java.util.Arrays;

import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.os.Handler;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
import android.preference.Preference.OnPreferenceClickListener;
import android.text.InputType;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;
import android.widget.TextView;
import de.avm.android.fritzapp.R;
import de.avm.android.fritzapp.util.CallRouteExceptions;
import de.avm.android.fritzapp.util.PhoneNumberHelper;
import de.avm.android.fritzapp.util.ResourceHelper;

/* GUI for the settings of call route exceptions */
public class SettingsRouteExceptionsActivity extends PreferenceActivity
{
	private static final String PREF_ASK_MOBILE_FALLBACK = "ask_mobile";
	private static final boolean PREF_ASK_MOBILE_FALLBACK_DEFAULT = true;

	private static final int MENU_ADD = 1;
	private static final int MENU_EDIT = 2;

	private CallRouteExceptions mCallRouteExceptions = null;
	private ListView mListView = null;
	private String mEditCallRouteException = null;

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

		setContentView(R.layout.settings);
		mListView = (ListView)findViewById(android.R.id.list);
		mListView.setSelector(R.drawable.list_selector_background);

		// Title
		ResourceHelper.setAltTitleSymbol(this);
		ResourceHelper.setTitle(this, R.string.settings_routeexceptions);

		// load list
		mCallRouteExceptions = new CallRouteExceptions(this);
	}

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

		if (mCallRouteExceptions != null)
			mCallRouteExceptions.save();
	}

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

	private void updateListAdapter()
	{
		mCallRouteExceptions.setOnChangedListener(null);
		PreferenceScreen root = getPreferenceManager().createPreferenceScreen(this);

		// request for fallback to mobile
		CheckBoxPreference checkPref = new CheckBoxPreference(this);
		checkPref.setKey(PREF_ASK_MOBILE_FALLBACK);
		checkPref.setDefaultValue(PREF_ASK_MOBILE_FALLBACK_DEFAULT);
		checkPref.setTitle(R.string.settings_ask_mobile_fallback);
		checkPref.setSummary(R.string.settings_ask_mobile_fallback2);
		root.addPreference(checkPref);

		// category list
		PreferenceCategory group = new PreferenceCategory(this);
		group.setTitle(R.string.settings_cat_routeexceptions);
		root.addPreference(group);

		if (mCallRouteExceptions.hasMobileExceptions())
		{
			// mobile exceptions
			checkPref = new CheckBoxPreference(this);
			checkPref.setPersistent(false);
			checkPref.setTitle(R.string.settings_callroute_mobile);
			checkPref.setSummary(R.string.settings_callroute_mobile2);
			checkPref.setChecked(mCallRouteExceptions.isMobileExceptions());
			checkPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener()
			{
				public boolean onPreferenceChange(Preference preference, Object newValue)
				{
					mCallRouteExceptions.setMobileExceptions(((Boolean)newValue).booleanValue());
					return true;
				}
			});
			group.addPreference(checkPref);
		}
		
		// exceptions list
		String[] callExceptions = mCallRouteExceptions.toArray(new String[0]);
		Arrays.sort(callExceptions, String.CASE_INSENSITIVE_ORDER);
		for (String callException : callExceptions)
			group.addPreference(new CallRoutePreference(this, callException));
		
		// add command
		Preference newPref = new Preference(this);
		newPref.setTitle(getString(R.string.settings_addrouteexception));
		newPref.setPersistent(false);
		newPref.setOnPreferenceClickListener(new OnPreferenceClickListener()
		{
			public boolean onPreferenceClick(Preference preference)
			{
				showDialog(MENU_ADD);
				return true;
			}
		});
		group.addPreference(newPref);
		root.setPersistent(false);
		root.bind(mListView);
		mListView.setAdapter(root.getRootAdapter());
		setPreferenceScreen(root);

		// update on changes
		mCallRouteExceptions.setOnChangedListener(new CallRouteExceptions.OnChangedListener()
		{
			private Handler mHandler = new Handler();
			
			public void onChanged()
			{
				mHandler.post(new Runnable()
				{
					public void run()
					{
						updateListAdapter();
					}
				});
			}
		});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu)
	{
		getMenuInflater().inflate(R.menu.routeexceptions_menu, menu);
		return true;
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu)
	{
		menu.findItem(R.id.Clear).setEnabled(mCallRouteExceptions.size() > 0);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) 
	{
		switch (item.getItemId())
		{
			case R.id.Clear:
				showDialog(R.id.Clear);
				return true;
		}
		return false;
	}

	@Override
	protected Dialog onCreateDialog(int id)
	{
		switch (id)
		{
			// remove all exceptions
			case R.id.Clear:
			{
				return TextDialog.create(this,
						getString(R.string.settings_routeexceptions),
						getString(R.string.ask_removeall),
						TextDialog.DEFAULT_EDIT_ICON).setPositiveButton(
						R.string.yes, new DialogInterface.OnClickListener()
						{
							public void onClick(DialogInterface dialogInterface,
									int id)
							{
								mCallRouteExceptions.clear();
								removeDialog(R.id.Clear);
							}
						}).setNegativeButton(R.string.no, new DialogInterface.OnClickListener()
						{
							public void onClick(DialogInterface dialogInterface, int id)
							{
								removeDialog(R.id.Clear);
							}
						})
						.setOnCancelListener(new OnCancelListener(R.id.Clear)).create();
			}
	
			// add new exception
			case MENU_ADD: 
			{
				return TextDialog.createEdit(this,
						getString(R.string.settings_addrouteexception), "",
						InputType.TYPE_CLASS_PHONE, 0,
						getString(R.string.settings_editrouteexception_hint))
						.setPositiveButton(R.string.ok,
								new DialogInterface.OnClickListener()
						{
							public void onClick(DialogInterface dialogInterface, int id)
							{
								onNewCallRouteException(
										((TextView)(((Dialog)dialogInterface)
										.findViewById(R.id.message))).getText()
										.toString());
								removeDialog(MENU_ADD);
							}
						}).setNegativeButton(R.string.cancel,
									new DialogInterface.OnClickListener()
						{
							public void onClick(DialogInterface dialogInterface, int id)
							{
								removeDialog(MENU_ADD);
							}
						})
						.setOnCancelListener(new OnCancelListener(MENU_ADD)).create();
			}
			
			// edit exception
			case MENU_EDIT:
			{
				return TextDialog.createEdit(this,
						getString(R.string.settings_editrouteexception),
						mEditCallRouteException,
						InputType.TYPE_CLASS_PHONE, 0,
						getString(R.string.settings_editrouteexception_hint))
						.setPositiveButton(R.string.ok,
								new DialogInterface.OnClickListener()
						{
							public void onClick(DialogInterface dialogInterface, int id)
							{
								onEditCallRouteException(((TextView)(((Dialog)dialogInterface)
										.findViewById(R.id.message))).getText()
										.toString());
								removeDialog(MENU_EDIT);
							}
						}).setNegativeButton(R.string.cancel,
									new DialogInterface.OnClickListener()
						{
							public void onClick(DialogInterface dialogInterface, int id)
							{
								mEditCallRouteException = null;
								removeDialog(MENU_EDIT);
							}
						})
						.setNeutralButton(R.string.settings_removerouteexception,
									new DialogInterface.OnClickListener()
						{
							public void onClick(DialogInterface dialogInterface, int id)
							{
								onEditCallRouteException(null);
								removeDialog(MENU_EDIT);
							}
						})
						.setOnCancelListener(new OnCancelListener(MENU_EDIT)).create();
			}
		}
		return null;
	}
	
	private void onNewCallRouteException(String newCallRouteException)
	{
		String pattern = PhoneNumberHelper.stripSeparators(
				newCallRouteException);
		if (!TextUtils.isEmpty(pattern) &&
				!mCallRouteExceptions.contains(pattern))
			mCallRouteExceptions.add(pattern);
	}
		
	private void onEditCallRouteException(String newCallRouteException)
	{
		String oldCallRouteException = mEditCallRouteException;
		mEditCallRouteException = null;
		
		int pos = (TextUtils.isEmpty(oldCallRouteException)) ? -1 :
				mCallRouteExceptions.indexOf(oldCallRouteException);
		if (pos >= 0)
		{		
			if (TextUtils.isEmpty(newCallRouteException))
			{
				mCallRouteExceptions.remove(pos);
			}
			else
			{
				String pattern = PhoneNumberHelper.stripSeparators(
						newCallRouteException);
				if (!TextUtils.isEmpty(pattern))
					mCallRouteExceptions.set(pos, pattern);
			}
		}
	}
	
	private class OnCancelListener implements DialogInterface.OnCancelListener
	{
		private int mId;
		
		public OnCancelListener(int id)
		{
			mId = id;
		}
		
		public void onCancel(DialogInterface dialog)
		{
			if (mId == MENU_EDIT) mEditCallRouteException = null;
			removeDialog(mId);
		}
	}

	private class CallRoutePreference extends Preference
	{
		public CallRoutePreference(Context context, String callException)
		{
			super(context);
			setTitle(callException);
		}

		public String getCallException()
		{
			return getTitle().toString();
		}
		
		@Override
	    protected void onClick()
	    {
			mEditCallRouteException = getCallException();
			showDialog(MENU_EDIT);
	    }
	}	
	
	/**
	 * Preparations on settings to do on app's start
	 * @param context context for reading and writing the settings
	 * @param firstRun true for first run after install
	 */
	public static void prepareSettings(Context context, boolean firstRun)
	{
		if (firstRun) CallRouteExceptions.saveDefault(context);
	}
	
	public static boolean isAskForMobileFallback(Context context)
	{
		return PreferenceManager.getDefaultSharedPreferences(context)
				.getBoolean(PREF_ASK_MOBILE_FALLBACK,
						PREF_ASK_MOBILE_FALLBACK_DEFAULT);
	}
	
	public static void setIsAskForMobileFallback(Context context, boolean on)
	{
		Editor editor = PreferenceManager.getDefaultSharedPreferences(context)
				.edit();
		editor.putBoolean(PREF_ASK_MOBILE_FALLBACK, on);
		editor.commit();
	}
}
