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

import de.avm.android.fritzapp.sipua.phone.CallerInfo;
import de.avm.android.tr064.model.ContactEmail;
import de.avm.android.tr064.model.ContactNumber;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.PhoneLookup;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.text.TextUtils;

/**
 * Wrapper for contacts API on Eclair and newer
 */
public class LocalContactsEclair extends LocalContacts
{
	private static final String[] SUMMARY_PROJECTION = new String[]
  	{
  		Contacts._ID,
  		Contacts.DISPLAY_NAME,
  		Contacts.LOOKUP_KEY,
  		Contacts.IN_VISIBLE_GROUP
  	};
	private static final int SUMMARY_PROJECTION_ID = 0;
	private static final int SUMMARY_PROJECTION_NAME = 1;
	private static final int SUMMARY_PROJECTION_LOOKUP_KEY = 2;

	private static final String[] CALLERINFO_PROJECTION = new String[]
	{
  		PhoneLookup._ID,
		PhoneLookup.DISPLAY_NAME,
		PhoneLookup.LOOKUP_KEY,
  		PhoneLookup.NUMBER,
  		PhoneLookup.TYPE,
  		PhoneLookup.LABEL,
  		PhoneLookup.CUSTOM_RINGTONE,
  		PhoneLookup.SEND_TO_VOICEMAIL
	};
	private static final int CALLERINFO_PROJECTION_ID = 0;
	private static final int CALLERINFO_PROJECTION_NAME = 1;
	private static final int CALLERINFO_PROJECTION_LOOKUP_KEY = 2;
	private static final int CALLERINFO_PROJECTION_NUMBER = 3;
	private static final int CALLERINFO_PROJECTION_TYPE = 4;
	private static final int CALLERINFO_PROJECTION_LABEL = 5;
	private static final int CALLERINFO_PROJECTION_CUSTOM_RINGTONE = 6;
	private static final int CALLERINFO_PROJECTION_SEND_TO_VOICEMAIL = 7;
	
	protected LocalContactsEclair()
	{
		// to create instance use LocalContacts.getInstance() only!
	}
	
	@Override
	public Uri getContentUri()
	{
		return Contacts.CONTENT_URI;
	}

	@Override
	public String getSelection()
	{
		return Contacts.IN_VISIBLE_GROUP + "=1";
	}

	@Override
	public Uri getSummaryUri()
	{
		return Contacts.CONTENT_URI;
	}

	@Override
	public String[] getSummaryProjection()
	{
		return SUMMARY_PROJECTION;
	}

	@Override
	public String getSummaryOrder()
	{
		return Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
	}
	
	@Override
	public Contact getSummaryItem(Context context, Cursor cursor)
	{
		Contact contact = new Contact();
		contact.setName(cursor.getString(SUMMARY_PROJECTION_NAME));
        contact.mUri = Contacts.getLookupUri(cursor.getLong(SUMMARY_PROJECTION_ID),
        		cursor.getString(SUMMARY_PROJECTION_LOOKUP_KEY));

        return contact;
	}

	@Override
	public Contact getContact(Context context, Uri contactUri)
			throws IllegalArgumentException
	{
		ContentResolver contentResolver = context.getContentResolver();
        Cursor cursor = contentResolver.query(contactUri,
        		getSummaryProjection(), getSelection(), null, null);
        try
        {
            if ((cursor != null) && cursor.moveToFirst())
            	return getContact(context, cursor);
            else
            	throw new IllegalArgumentException("No contact with this URI found.");
        }
        finally
        {
        	if (cursor != null) cursor.close();
        }
	}

	@Override
	public Contact getContact(Context context, Cursor cursor)
			throws IllegalArgumentException
	{
		Contact contact = new Contact();
        long contactId = cursor.getLong(SUMMARY_PROJECTION_ID);
		contact.mUri = Contacts.getLookupUri(contactId,
        		cursor.getString(SUMMARY_PROJECTION_LOOKUP_KEY));

		// get name
    	contact.setName(cursor.getString(SUMMARY_PROJECTION_NAME));

		// get phone numbers
		ContentResolver contentResolver = context.getContentResolver();
        cursor = contentResolver.query(Phone.CONTENT_URI,
                new String[]{Phone.NUMBER, Phone.TYPE, Phone.LABEL},
                Phone.CONTACT_ID + "=" + contactId, null,
                Phone.IS_SUPER_PRIMARY + " DESC");
        if (cursor != null)
        {
	        try
	        {
	        	for (boolean bb = cursor.moveToFirst(); bb; bb = cursor.moveToNext())
	            {
	            	ContactNumber number = new ContactNumber();
	            	number.setNumber(cursor.getString(0));
	            	if (!TextUtils.isEmpty(number.getAddress()))
	            	{
	            		int type = cursor.getInt(1);
	            		switch (type)
	            		{
	            			case Phone.TYPE_HOME:
	            				number.setType(ContactNumber.Type.HOME);
	            				break;
	            			case Phone.TYPE_WORK:
	            				number.setType(ContactNumber.Type.WORK);
	            				break;
	            			case Phone.TYPE_MOBILE:
	            				number.setType(ContactNumber.Type.MOBILE);
	            				break;
	            			case Phone.TYPE_FAX_HOME:
	            				number.setType(ContactNumber.Type.FAX_HOME);
	            				break;
	            			case Phone.TYPE_FAX_WORK:
	            				number.setType(ContactNumber.Type.FAX_WORK);
	            				break;
	            			case Phone.TYPE_PAGER:
	            				number.setType(ContactNumber.Type.PAGER);
	            				break;
	            			default:
	                    		number.setCustomType(Phone.getTypeLabel(context.getResources(),
	                    				type, cursor.getString(2)).toString());
	            				break;
	            		}
	                	contact.mAddresses.add(number);
	            	}
	            }
	        }
	        finally
	        {
	            cursor.close();
	        }
        }
        
        // get email addresses
        cursor = contentResolver.query(Email.CONTENT_URI,
                new String[]{Email.DATA, Email.TYPE, Email.LABEL},
                Email.CONTACT_ID + "=" + contactId, null,
                Email.IS_SUPER_PRIMARY + " DESC");
        if (cursor != null)
        {
	        try
	        {
	        	for (boolean bb = cursor.moveToFirst(); bb; bb = cursor.moveToNext())
	            {
	        		ContactEmail email = new ContactEmail();
	        		email.setEmail(cursor.getString(0));
	            	if (!TextUtils.isEmpty(email.getAddress()))
	            	{
	            		int type = cursor.getInt(1);
	            		switch (type)
	            		{
	            			case Email.TYPE_HOME:
	            				email.setType(ContactEmail.Type.PRIVATE);
	            				break;
	            			case Email.TYPE_WORK:
	            				email.setType(ContactEmail.Type.BUSINESS);
	            				break;
	            			case Email.TYPE_OTHER:
	            				email.setType(ContactEmail.Type.OTHER);
	            				break;
	            			default:
	    	            		email.setCustomType(Email.getTypeLabel(context.getResources(),
	    	            				type, cursor.getString(2)).toString());
	            				break;
	            		}
	                	contact.mAddresses.add(email);
	            	}
	            }
	        }
	        finally
	        {
	            cursor.close();
	        }
        }

        return contact;
	}

	@Override
	public void markAsContacted(Context context, Uri contactUri)
	{
		ContentResolver contentResolver = context.getContentResolver();
        Cursor cursor = contentResolver.query(contactUri,
                new String[]{Contacts._ID}, getSelection(), null, null);
        
        if (cursor != null)
        {
	        try
	        {
	            if (cursor.moveToFirst())
	            	Contacts.markAsContacted(contentResolver, cursor.getLong(0));
	        }
	        finally
	        {
	            cursor.close();
	        }
        }
	}

	@Override
	public InputStream openContactPhotoInputStream (Context context,
			Uri contactUri)
	{
		return Contacts.openContactPhotoInputStream(context.getContentResolver(),
				contactUri);
	}

	@Override
	public CharSequence getDisplayPhoneLabel(Context context,
			int type, CharSequence label)
	{
		return Phone.getTypeLabel(context.getResources(), type, label);
	}

	@Override
	public Uri getCallerInfoUri(String number)
	{
		return Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
				Uri.encode(number));
	}

	@Override
	public String[] getCallerInfoProjection()
	{
		return CALLERINFO_PROJECTION;
	}

	@Override
	public CallerInfo getCallerInfoItem(Context context, Cursor cursor)
	{
		CallerInfo info = new CallerInfo();
		info.contactRefUri = Contacts.getLookupUri(cursor.getLong(CALLERINFO_PROJECTION_ID),
        		cursor.getString(CALLERINFO_PROJECTION_LOOKUP_KEY));
		
		info.name = cursor.getString(CALLERINFO_PROJECTION_NAME);

		info.phoneNumber = cursor.getString(CALLERINFO_PROJECTION_NUMBER);
        if ((info.phoneNumber != null) && (info.phoneNumber.length() > 0))
        {
        	int type = cursor.getInt(CALLERINFO_PROJECTION_TYPE);
        	if (type != 0)
        	{
        		info.numberType = type;
        		info.numberLabel = cursor.getString(CALLERINFO_PROJECTION_LABEL);
        		info.phoneLabel = Phone.getTypeLabel(context.getResources(),
        				type, info.numberLabel).toString();
        	}
        }
        
        String ringtone = cursor.getString(CALLERINFO_PROJECTION_CUSTOM_RINGTONE);
        info.contactRingtoneUri = ((ringtone == null) || (ringtone.length() == 0)) ?
        		null : Uri.parse(ringtone);
        
        info.shouldSendToVoicemail = (1 == cursor
        		.getInt(CALLERINFO_PROJECTION_SEND_TO_VOICEMAIL));
		
		return info;
	}
}
