/*
 * Copyright (C) 2010 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.contacts.editor;

import android.content.Context;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.ContactsContract.Contacts;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.android.contacts.R;
import com.android.contacts.editor.AggregationSuggestionEngine.RawContact;
import com.android.contacts.editor.AggregationSuggestionEngine.Suggestion;
import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.common.model.AccountTypeManager;
import com.android.contacts.common.model.account.AccountType;

import com.google.common.collect.Lists;

import java.util.ArrayList;
import java.util.List;

/**
 * A view that contains a name, picture and other data for a contact aggregation suggestion.
 */
public class AggregationSuggestionView extends LinearLayout {

    public interface Listener {

        /**
         * Callback that passes the contact ID to join with and, for convenience,
         * also the list of constituent raw contact IDs to avoid a separate query
         * for those.
         */
        public void onJoinAction(long contactId, List<Long> rawContacIds);

        /**
         * Callback that passes the contact ID to edit instead of the current contact.
         */
        public void onEditAction(Uri contactLookupUri);
    }

    private Listener mListener;
    private long mContactId;
    private String mLookupKey;
    private List<RawContact> mRawContacts = Lists.newArrayList();
    private boolean mNewContact;

    public AggregationSuggestionView(Context context) {
        super(context);
    }

    public AggregationSuggestionView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public AggregationSuggestionView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public void setNewContact(boolean flag) {
        mNewContact = flag;
    }

    public void bindSuggestion(Suggestion suggestion) {
        mContactId = suggestion.contactId;
        mLookupKey = suggestion.lookupKey;
        mRawContacts = suggestion.rawContacts;
        ImageView photo = (ImageView) findViewById(R.id.aggregation_suggestion_photo);
        if (suggestion.photo != null) {
            photo.setImageBitmap(BitmapFactory.decodeByteArray(
                    suggestion.photo, 0, suggestion.photo.length));
        } else {
            photo.setImageDrawable(ContactPhotoManager.getDefaultAvatarDrawableForContact(
                    getResources(), false, null));
        }

        TextView name = (TextView) findViewById(R.id.aggregation_suggestion_name);
        name.setText(suggestion.name);

        TextView data = (TextView) findViewById(R.id.aggregation_suggestion_data);
        String dataText = null;
        if (suggestion.nickname != null) {
            dataText = suggestion.nickname;
        } else if (suggestion.emailAddress != null) {
            dataText = suggestion.emailAddress;
        } else if (suggestion.phoneNumber != null) {
            dataText = suggestion.phoneNumber;
        }
        data.setText(dataText);
    }

    /**
     * Returns true if the suggested contact can be edited.
     */
    private boolean canEditSuggestedContact() {
        if (!mNewContact) {
            return false;
        }

        AccountTypeManager accountTypes = AccountTypeManager.getInstance(getContext());
        for (RawContact rawContact : mRawContacts) {
            String accountType = rawContact.accountType;
            String dataSet = rawContact.dataSet;
            if (accountType == null) {
                return true;
            }
            AccountType type = accountTypes.getAccountType(accountType, dataSet);
            if (type.areContactsWritable()) {
                return true;
            }
        }

        return false;
    }

    public void setListener(Listener listener) {
        mListener = listener;
    }

    public boolean handleItemClickEvent() {
        if (mListener != null && isEnabled()) {
            if (canEditSuggestedContact()) {
                if (TextUtils.isEmpty(mLookupKey)) {
                    return false;
                }
                mListener.onEditAction(Contacts.getLookupUri(mContactId, mLookupKey));
            } else {
                ArrayList<Long> rawContactIds = Lists.newArrayList();
                for (RawContact rawContact : mRawContacts) {
                    rawContactIds.add(rawContact.rawContactId);
                }
                mListener.onJoinAction(mContactId, rawContactIds);
            }
            return true;
        }
        return false;
    }
}
