/* 
 * 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.net.URL;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.media.RingtoneManager;
import android.os.Bundle;
import android.os.Handler;
import android.preference.CheckBoxPreference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;
import de.avm.android.fritzapp.R;
import de.avm.android.fritzapp.com.ComSettingsChecker;
import de.avm.android.fritzapp.com.discovery.BoxInfo;
import de.avm.android.fritzapp.service.BoxServiceConnection;
import de.avm.android.fritzapp.sipua.ui.SipRingtonePreference;
import de.avm.android.fritzapp.sipua.ui.Sipdroid;
import de.avm.android.fritzapp.util.PhoneNumberHelper;
import de.avm.android.fritzapp.util.ResourceHelper;
import de.avm.android.tr064.Tr064Boxinfo;
import de.avm.android.tr064.Tr064Capabilities;

/* GUI for the settings of the app */
public class SettingsActivity extends PreferenceActivity
{
	private static final String TAG = "SettingsActivity";
	
	private static final int ORDER_NORMAL = 1; 
	private static final int ORDER_TAM = 2; 
	private static final int ORDER_APPEND = 3; 

	// no prefs any more
	public static final String PREF_BOX_UDN = "box_udn";
	public static final String PREF_PASS = "fritzappENC";
	private static final String PREF_TAM = "tam";
	private static final String PREF_CALLROUTE = "callroute";
	private static final String PREF_CALLROUTE_FON = "call_phone";

	private String mUdn = "";
	private Tr064Capabilities mTr064Capabilities = null;

	private PreferenceCategory mBoxCategory = null;
	private PreferenceScreen mBoxPref = null;
	private PreferenceScreen mSipPref = null;
	private PreferenceCategory mPropertiesCategory = null;
	private TamPreference mTamPref = null;
	
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);

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

		PreferenceScreen screen = createPreferenceScreen(savedInstanceState);
		screen.setPersistent(true);
		screen.bind(preferenceView);
		preferenceView.setAdapter(screen.getRootAdapter());
		setPreferenceScreen(screen);

		ResourceHelper.setAltTitleSymbol(this);
		ResourceHelper.setTitle(this, 0);
	}

	@Override
	public void onResume()
	{
		super.onResume();
		if (!mBoxServiceConnection.bindService(getApplicationContext()))
			Log.w(TAG, "Failed to bind to BoxService.");
		onStatusChanged();
	}
	
	@Override
	public void onPause()
	{
		super.onPause();
		mBoxServiceConnection.unbindService();
	}
	
	private BoxServiceConnection mBoxServiceConnection = new BoxServiceConnection()
	{
		public void onComStatusChanged()
		{
			runOnUiThread(new Runnable()
			{
				public void run()
				{
					onStatusChanged();
				}
			});
		}
	};

	/**
	 * Creates the preference screen. Use standardframework of android
	 * 
	 * @return the preference screen
	 */
	private PreferenceScreen createPreferenceScreen(Bundle savedInstanceState)
	{
		PreferenceScreen root = getPreferenceManager()
				.createPreferenceScreen(this);

		// category Box
		mBoxCategory = new PreferenceCategory(this);
		mBoxCategory.setTitle(R.string.pref_cat_box);
		root.addPreference(mBoxCategory);

		// select box
		mBoxPref = getPreferenceManager().createPreferenceScreen(this);
		mBoxPref.setTitle(R.string.pref_address);
		mBoxPref.setIntent(new Intent(this,
				SettingsFritzBoxActivity.class));
		mBoxCategory.addPreference(mBoxPref);

		// VoIP client
		mSipPref = getPreferenceManager().createPreferenceScreen(this);
		mSipPref.setTitle(R.string.settings_voipconfig);
		mSipPref.setIntent(new Intent(this, SettingsVoIPConfigActivity.class));
		mSipPref.setEnabled(false);
		
		// category SIP
		mPropertiesCategory = new PreferenceCategory(this);
		mPropertiesCategory.setTitle(R.string.pref_cat_sip);
		root.addPreference(mPropertiesCategory);

		// ringtone
		SipRingtonePreference ringtonePref = new SipRingtonePreference(this);
		ringtonePref.setKey(Sipdroid.PREF_RINGTONE);
		ringtonePref.setTitle(R.string.settings_sipringtone);
		ringtonePref.setSummary(R.string.settings_sipringtone2);
		ringtonePref.setRingtoneType(RingtoneManager.TYPE_RINGTONE);
		ringtonePref.setPersistent(false);
		ringtonePref.setOrder(ORDER_NORMAL);
		mPropertiesCategory.addPreference(ringtonePref);

		// CLIR
		CheckBoxPreference clirPref = new CheckBoxPreference(this);
		clirPref.setKey(PhoneNumberHelper.PREF_CLIR);
		clirPref.setDefaultValue(PhoneNumberHelper.DEFAULT_CLIR);
		clirPref.setTitle(R.string.settings_clir);
		clirPref.setSummary(R.string.settings_clir2);
		clirPref.setOrder(ORDER_NORMAL);
		mPropertiesCategory.addPreference(clirPref);

		// TAM
		mTamPref = new TamPreference(this, savedInstanceState == null);
		mTamPref.setOnChangedListener(new TamPreference.OnChangedListener()
		{
			public void onChanged(boolean isInSettings)
			{
				showTamPref(isInSettings);
			}
		});
		mTamPref.setTitle(R.string.settings_tam);
		mTamPref.setDialogTitle(R.string.settings_tam);
		mTamPref.setActive(false);
		mTamPref.setOrder(ORDER_TAM);
		 
		// exception list
		final PreferenceScreen expPref =
				getPreferenceManager().createPreferenceScreen(this);
		expPref.setTitle(R.string.settings_routeexceptions);
		expPref.setIntent(new Intent(this,
				SettingsRouteExceptionsActivity.class));
		expPref.setSummary(R.string.settings_routeexceptions2);
		expPref.setOrder(ORDER_APPEND);
		mPropertiesCategory.addPreference(expPref);

		return root;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu)
	{
	    getMenuInflater().inflate(R.menu.settings_menu, menu);
		return true;
	}
		
	@Override
	public boolean onOptionsItemSelected(MenuItem item)
	{
		switch (item.getItemId())
		{
			case R.id.Extended:
				startActivity(new Intent(this, SettingsExtendedActivity.class));
				break;
		}
		return true;
	}

	private void onStatusChanged()
	{
		// connection might have changed

		// currently connected box
		BoxInfo boxInfo = ComSettingsChecker.getBoxInfo();
		if (boxInfo == null)
		{
			// no box
			mUdn = "";
			mTr064Capabilities = null;

			// Box
			if (mBoxPref != null)
				mBoxPref.setSummary(R.string.pref_address2_notconnected);
			
			// VoIP client
			if (mSipPref != null)
			{
				showSipPref(false);
				mSipPref.setSummary("");
			}
			
			// TAM
			if (mTamPref != null)
			{
				showTamPref(false);
			}
			return;
		}

		Tr064Boxinfo tr064Info = boxInfo.getTr064Boxinfo();
		Tr064Capabilities tr064Capabilities = (tr064Info == null) ?
				Tr064Capabilities.EMPTY : tr064Info.getTr064Capabilities(); 
		boolean boxChanged = !boxInfo.getUdn().equals(mUdn) ||
				(!tr064Capabilities.equals(mTr064Capabilities));
		mUdn = boxInfo.getUdn();
		mTr064Capabilities = tr064Capabilities; 

		// Box
		if (mBoxPref != null)
		{
			if (tr064Capabilities.has(ComSettingsChecker.MANDATORY_TR064_CAPABILITIES))
			{
				URL location = boxInfo.getLocation(); 
				mBoxPref.setSummary(String.format(
						getString(R.string.pref_address2_connected_fmt),
						(location == null) ? "" : location.getHost()));
			}
			else mBoxPref.setSummary(R.string.pref_address2_notconnected);
		}
		
		// VoIP client
		if ((mBoxCategory != null) && (mSipPref != null))
		{
			if (tr064Capabilities.has(Tr064Capabilities.Capability.VOIP_CONF))
			{
				if (boxInfo.hasVoipCredentials())
					mSipPref.setSummary(boxInfo.getVoIPTitle());
				else
					mSipPref.setSummary(R.string.pref_not_configured);
			}
			else mSipPref.setSummary("");
			if (boxChanged)
			{
				final Handler handler = new Handler();
				boolean showIt = SettingsVoIPConfigActivity.isInSettings(this,
						new SettingsVoIPConfigActivity.OnIsInSettingsListener()
				{
					public void onIsInSettings(final String udn, final boolean result)
					{
						handler.post(new Runnable()
						{
							public void run()
							{
								BoxInfo info = ComSettingsChecker.getBoxInfo();
								if ((info != null) && info.getUdn().equals(udn))
									showSipPref(result); // still the same box
							}
						});
					}
				});
				showSipPref(showIt);
			}
		}
		
		// TAM
		if ((mPropertiesCategory != null) && (mTamPref != null))
		{
			if (tr064Capabilities.has(Tr064Capabilities.Capability.TAM))
			{
				if (boxChanged)
				{
					final Handler handler = new Handler();
					boolean showIt = TamPreference.isInSettings(this, 
							new TamPreference.OnResultListener<Boolean>()
					{
						public void onResult(final String udn, final Boolean result)
						{
							handler.post(new Runnable()
							{
								public void run()
								{
									BoxInfo info = ComSettingsChecker.getBoxInfo();
									if ((info != null) && info.getUdn().equals(udn))
										showTamPref(result.booleanValue());  // still the same box
								}
							});
						}
	
						public void onError(Exception error)
						{
							// don't change
						}
					});
					showTamPref(showIt);
				}
			}
			else showTamPref(false);
		}
	}

	private void showSipPref(boolean showIt)
	{
		if (showIt != mSipPref.isEnabled())
		{
			if (showIt)
			{
				mSipPref.setEnabled(true);
				mBoxCategory.addPreference(mSipPref);
			}
			else
			{
				mSipPref.setEnabled(false);
				mBoxCategory.removePreference(mSipPref);
			}
		}
	}
	
	private void showTamPref(boolean showIt)
	{
		if (showIt != mTamPref.isActive())
		{
			if (showIt)
			{
				mTamPref.setActive(true);
				mPropertiesCategory.addPreference(mTamPref); 
			}
			else
			{
				mTamPref.setActive(false);
				mPropertiesCategory.removePreference(mTamPref);
			}
		}
	}
	
	/**
	 * 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)
	{
		SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(context); 

		// import old setting on update
		String udn = prefs.getString(PREF_BOX_UDN, "");
		if (udn.length() > 0)
		{
			String defaultVoipTitle = String.format(context.getString(
					R.string.settings_new_voipclient_name_fmt), "");
			ComSettingsChecker.getBoxes().importBox(
					context.getApplicationContext(), udn,
					prefs.getString(PREF_PASS, ""),
					prefs.getString(Sipdroid.PREF_SIPUSER, ""),
					prefs.getString(Sipdroid.PREF_SIPPASS, ""),
					prefs.getString(SettingsVoIPConfigActivity.PREF_VOIPCLIENT_NAME,
							defaultVoipTitle),
					prefs.getString(PREF_TAM, ""));
		}

		Editor edit = prefs.edit();

		// remove old settings
		edit.remove(PREF_CALLROUTE);
		edit.remove(PREF_CALLROUTE_FON);
		edit.remove(PREF_TAM);
		
		// remove value of Test-Version
		edit.remove(Sipdroid.PREF_EARGAIN);

		edit.commit();

		SettingsFritzBoxActivity.prepareSettings(context, firstRun);
		SettingsVoIPConfigActivity.prepareSettings(context, firstRun);
		SettingsExtendedActivity.prepareSettings(context, firstRun);
		SettingsTestActivity.prepareSettings(context, firstRun);
	}
}
