/*
 * 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.Config;
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 (Config.LOGD) 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 (Config.LOGD) {
                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 (Config.LOGD) 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 (Config.LOGD) 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 (Config.LOGD) Log.d(TAG, "getVoiceContactsFromFile failed " + e);
        }
        finally {
            try {
                br.close();
            } catch (IOException e) {
                if (Config.LOGD) Log.d(TAG, "getVoiceContactsFromFile failed during close " + e);
            }
        }

        if (Config.LOGD) 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 (Config.LOGD) Log.d(TAG, "redialNumber " + number);

        return number;
    }

}
