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

import java.util.Locale;

import de.avm.android.fritzapp.com.ComSettingsChecker;
import de.avm.android.fritzapp.com.JasonBoxinfo;

import android.content.Context;
import android.preference.PreferenceManager;

/**
 * Helpers to be used with phone numbers
 */
public class PhoneNumberHelper
{
	public static final String PREF_CLIR = "clir";
	public static final boolean DEFAULT_CLIR = false;
	private static final String CLIR_ON = "*31#";
	private static final String CLIR_OFF = "#31#";

	private static final int NO_FIXNUMBER_VERSION_MAJOR = 5;
	private static final int NO_FIXNUMBER_VERSION_MINOR = 5;
	private static class CountryInfo
	{
		public String mCountry;
		public String[] mInternationalPrefixes;
		public String mReplacement;
		
		public CountryInfo(String country, String[] prefixes, String replacement)
		{
			mCountry = country; mInternationalPrefixes = prefixes; mReplacement = replacement;
		}
		
		public int match(String number)
		{
			for(String prefix : mInternationalPrefixes)
				if (number.startsWith(prefix)) return prefix.length();
			return 0;
		}
	}
	private static final CountryInfo[] COUNTRY_INFOS = new CountryInfo[]
	{
		new CountryInfo("DE", new String[] { "+49", "0049" }, "0"),
		new CountryInfo("AT", new String[] { "+43", "0043" }, "0"),
		new CountryInfo("CH", new String[] { "+41", "0041" }, "0"),
	};

	private static final String VALID_CHAR = "+0123456789*#";
	private static final String[] mInternalNumbers = new String[]
	{
		"**1", "**2", "**59", "**6", "**7", "**8", "**9" 
	}; 
	
	/**
	 * Strips international dialing prefix for national calls in
	 * some countries for older boxes 
	 * @param number
	 * @return fixed number
	 */
	public static String fixInternationalDialingPrefix(String number)
	{
		JasonBoxinfo jasonBoxInfo = ComSettingsChecker.getJasonBoxinfo();
		if ((jasonBoxInfo != null) &&
				(jasonBoxInfo.compareVersion(NO_FIXNUMBER_VERSION_MAJOR,
						NO_FIXNUMBER_VERSION_MINOR) < 0))
		{
			String whereAmI = Locale.getDefault().getCountry();
			for (CountryInfo info : COUNTRY_INFOS)
				if (info.mCountry.equalsIgnoreCase(whereAmI))
				{
					int len = info.match(number);
					if (len > 0)
					{
						number = info.mReplacement + number.substring(len);
						break;
					}
				}
		}
		return number;
	}
	
	public static boolean isInternalNumber(String number)
	{
		if ((number != null) && (number.length() > 0))
			for (String prefix : mInternalNumbers)
				if (number.startsWith(prefix))
					return true;
		return false;
	}
	
	/**
	 * Strips invalid characters from phone number
	 * @param number
	 * @return
	 */
	public static String stripSeparators(String number)
	{
		StringBuilder builder = new StringBuilder(number.length());
		char[] chars = number.toCharArray();
		for(char ch : chars)
			if (VALID_CHAR.indexOf(ch) >= 0)
				builder.append(ch);
		return builder.toString();
	}
	
	/**
	 * Gets CLIR preference
	 * @param context context to access saved preferences
	 * @return CLIR preference
	 */
	public static boolean isClir(Context context)
	{
		return PreferenceManager.getDefaultSharedPreferences(context) 
				.getBoolean(PREF_CLIR, DEFAULT_CLIR);
	}
	
	/**
	 * Adds prefixes to phone number according to settings
	 * @param context context to access saved preferences
	 * @param number
	 * @return decorated number
	 */
	public static String decorateNumber(Context context, String number)
	{
		if (isClir(context))
			return CLIR_ON + number;
		return number;
	}
	
	/**
	 * Adds prefixes to phone number according to settings
	 * @param context context to access saved preferences
	 * @param override true to invert preference
	 * @param number
	 * @return decorated number
	 */
	public static String decorateNumber(Context context, boolean override, String number)
	{
		if (isClir(context) != override)
			return CLIR_ON + number;
		return number;
	}
	
	/**
	 * Strips known prefixes from beginning of phone number
	 * @param number possibly decorated phone number
	 * @return number phone number
	 */
	public static String stripNumber(String number)
	{
		if ((number != null) && (number.length() > 0))
		{
			for (int ii = 0; true;)
			{
				if (number.startsWith(CLIR_ON, ii))
				{
					ii += CLIR_ON.length();
				}
				else if (number.startsWith(CLIR_OFF, ii))
				{
					ii += CLIR_OFF.length();
				}
				else
				{
					number = number.substring(ii);
					break;
				}
			}
		}
		return number;
	}
}
