/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * 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 com.android.voicedialer;

import android.app.Activity;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.CallLog;
import android.util.Log;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


/**
 * This class represents a person who may be called via the VoiceDialer app.
 * The person has a name and a list of phones (home, mobile, work, other).
 */
public class VoiceContact {
    private static final String TAG = "VoiceContact";

    /**
     * Corresponding row doesn't exist.
     */
    public static final long ID_UNDEFINED = -1;

    public final String mName;
    public final long mContactId;
    public final long mPrimaryId;
    public final long mHomeId;
    public final long mMobileId;
    public final long mWorkId;
    public final long mOtherId;

    /**
     * Constructor.
     *
     * @param name person's name.
     * @param contactId ID in person table.
     * @param primaryId primary ID in phone table.
     * @param homeId home ID in phone table.
     * @param mobileId mobile ID in phone table.
     * @param workId work ID in phone table.
     * @param otherId other ID in phone table.
     */
    private VoiceContact(String name, long contactId, long primaryId,
            long homeId, long mobileId, long workId,long otherId) {
        mName = name;
        mContactId = contactId;
        mPrimaryId = primaryId;
        mHomeId = homeId;
        mMobileId = mobileId;
        mWorkId = workId;
        mOtherId = otherId;
    }

    @Override
    public int hashCode() {
        final int LARGE_PRIME = 1610612741;
        int hash = 0;
        hash = LARGE_PRIME * (hash + (int)mContactId);
        hash = LARGE_PRIME * (hash + (int)mPrimaryId);
        hash = LARGE_PRIME * (hash + (int)mHomeId);
        hash = LARGE_PRIME * (hash + (int)mMobileId);
        hash = LARGE_PRIME * (hash + (int)mWorkId);
        hash = LARGE_PRIME * (hash + (int)mOtherId);
        return mName.hashCode() + hash;
    }

    @Override
    public String toString() {
        return "mName=" + mName
                + " mPersonId=" + mContactId
                + " mPrimaryId=" + mPrimaryId
                + " mHomeId=" + mHomeId
                + " mMobileId=" + mMobileId
                + " mWorkId=" + mWorkId
                + " mOtherId=" + mOtherId;
    }

    /**
     * @param activity The VoiceDialerActivity instance.
     * @return List of {@link VoiceContact} from
     * the contact list content provider.
     */
    public static List<VoiceContact> getVoiceContacts(Activity activity) {
        if (false) Log.d(TAG, "VoiceContact.getVoiceContacts");

        List<VoiceContact> contacts = new ArrayList<VoiceContact>();

        String[] phonesProjection = new String[] {
            Phone._ID,
            Phone.TYPE,
            Phone.IS_PRIMARY,
            // TODO: handle type != 0,1,2, and use LABEL
            Phone.LABEL,
            Phone.DISPLAY_NAME,
            Phone.CONTACT_ID,
        };

        // Table is sorted by number of times contacted and name. If we cannot fit all contacts
        // in the recognizer, we will at least have the commonly used ones.
        Cursor cursor = activity.getContentResolver().query(
                Phone.CONTENT_URI, phonesProjection,
                Phone.NUMBER + " NOT NULL", null,
                Phone.LAST_TIME_CONTACTED + " DESC, " + Phone.DISPLAY_NAME + " ASC");

        final int phoneIdColumn = cursor.getColumnIndexOrThrow(Phone._ID);
        final int typeColumn = cursor.getColumnIndexOrThrow(Phone.TYPE);
        final int isPrimaryColumn = cursor.getColumnIndexOrThrow(Phone.IS_PRIMARY);
        final int labelColumn = cursor.getColumnIndexOrThrow(Phone.LABEL);
        final int nameColumn = cursor.getColumnIndexOrThrow(Phone.DISPLAY_NAME);
        final int personIdColumn = cursor.getColumnIndexOrThrow(Phone.CONTACT_ID);

        // pieces of next VoiceContact
        String name = null;
        long personId = ID_UNDEFINED;
        long primaryId = ID_UNDEFINED;
        long homeId = ID_UNDEFINED;
        long mobileId = ID_UNDEFINED;
        long workId = ID_UNDEFINED;
        long otherId = ID_UNDEFINED;

        // loop over phone table
        for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
            long phoneIdAtCursor = cursor.getLong(phoneIdColumn);
            int typeAtCursor = cursor.getInt(typeColumn);
            long isPrimaryAtCursor = cursor.getLong(isPrimaryColumn);
            String labelAtCursor = cursor.getString(labelColumn);
            String nameAtCursor = cursor.getString(nameColumn);
            long personIdAtCursor = cursor.getLong(personIdColumn);

            /*
            if (false) {
                Log.d(TAG, "phoneId=" + phoneIdAtCursor
                        + " type=" + typeAtCursor
                        + " isPrimary=" + isPrimaryAtCursor
                        + " label=" + labelAtCursor
                        + " name=" + nameAtCursor
                        + " personId=" + personIdAtCursor
                        );
            }
            */

            // encountered a new name, so generate current VoiceContact
            if (name != null && !name.equals(nameAtCursor)) {
                contacts.add(new VoiceContact(name, personId, primaryId,
                        homeId, mobileId, workId, otherId));
                name = null;
            }

            // start accumulating pieces for a new VoiceContact
            if (name == null) {
                name = nameAtCursor;
                personId = personIdAtCursor;
                primaryId = ID_UNDEFINED;
                homeId = ID_UNDEFINED;
                mobileId = ID_UNDEFINED;
                workId = ID_UNDEFINED;
                otherId = ID_UNDEFINED;
            }

            // if labeled, then patch to HOME/MOBILE/WORK/OTHER
            if (typeAtCursor == Phone.TYPE_CUSTOM &&
                    labelAtCursor != null) {
                String label = labelAtCursor.toLowerCase();
                if (label.contains("home") || label.contains("house")) {
                    typeAtCursor = Phone.TYPE_HOME;
                }
                else if (label.contains("mobile") || label.contains("cell")) {
                    typeAtCursor = Phone.TYPE_MOBILE;
                }
                else if (label.contains("work") || label.contains("office")) {
                    typeAtCursor = Phone.TYPE_WORK;
                }
                else if (label.contains("other")) {
                    typeAtCursor = Phone.TYPE_OTHER;
                }
            }

            // save the home, mobile, or work phone id
            switch (typeAtCursor) {
                case Phone.TYPE_HOME:
                    homeId = phoneIdAtCursor;
                    if (isPrimaryAtCursor != 0) {
                        primaryId = phoneIdAtCursor;
                    }
                    break;
                case Phone.TYPE_MOBILE:
                    mobileId = phoneIdAtCursor;
                    if (isPrimaryAtCursor != 0) {
                        primaryId = phoneIdAtCursor;
                    }
                    break;
                case Phone.TYPE_WORK:
                    workId = phoneIdAtCursor;
                    if (isPrimaryAtCursor != 0) {
                        primaryId = phoneIdAtCursor;
                    }
                    break;
                case Phone.TYPE_OTHER:
                    otherId = phoneIdAtCursor;
                    if (isPrimaryAtCursor != 0) {
                        primaryId = phoneIdAtCursor;
                    }
                    break;
            }
        }

        // generate the last VoiceContact
        if (name != null) {
            contacts.add(new VoiceContact(name, personId, primaryId,
                            homeId, mobileId, workId, otherId));
        }

        // clean up cursor
        cursor.close();

        if (false) Log.d(TAG, "VoiceContact.getVoiceContacts " + contacts.size());

        return contacts;
    }

    /**
     * @param contactsFile File containing a list of names,
     * one per line.
     * @return a List of {@link VoiceContact} in a File.
     */
    public static List<VoiceContact> getVoiceContactsFromFile(File contactsFile) {
        if (false) Log.d(TAG, "getVoiceContactsFromFile " + contactsFile);

        List<VoiceContact> contacts = new ArrayList<VoiceContact>();

        // read from a file
        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader(contactsFile), 8192);
            String name;
            for (int id = 1; (name = br.readLine()) != null; id++) {
                contacts.add(new VoiceContact(name, id, ID_UNDEFINED,
                        ID_UNDEFINED, ID_UNDEFINED, ID_UNDEFINED, ID_UNDEFINED));
            }
        }
        catch (IOException e) {
            if (false) Log.d(TAG, "getVoiceContactsFromFile failed " + e);
        }
        finally {
            try {
                br.close();
            } catch (IOException e) {
                if (false) Log.d(TAG, "getVoiceContactsFromFile failed during close " + e);
            }
        }

        if (false) Log.d(TAG, "getVoiceContactsFromFile " + contacts.size());

        return contacts;
    }

    /**
     * @param activity The VoiceDialerActivity instance.
     * @return String of last number dialed.
     */
    public static String redialNumber(Activity activity) {
        Cursor cursor = activity.getContentResolver().query(
                CallLog.Calls.CONTENT_URI,
                new String[] { CallLog.Calls.NUMBER },
                CallLog.Calls.TYPE + "=" + CallLog.Calls.OUTGOING_TYPE,
                null,
                CallLog.Calls.DEFAULT_SORT_ORDER + " LIMIT 1");
        String number = null;
        if (cursor.getCount() >= 1) {
            cursor.moveToNext();
            int column = cursor.getColumnIndexOrThrow(CallLog.Calls.NUMBER);
            number = cursor.getString(column);
        }
        cursor.close();

        if (false) Log.d(TAG, "redialNumber " + number);

        return number;
    }

}
