/*
 * Copyright (C) 2015 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.common.list;

import android.content.Context;
import android.database.Cursor;
import android.provider.ContactsContract;
import android.view.View;
import android.widget.CheckBox;

import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.group.GroupUtil;

import java.util.TreeSet;

/**
 * An extension of the default contact adapter that adds checkboxes and the ability
 * to select multiple contacts.
 */
public abstract class MultiSelectEntryContactListAdapter extends ContactEntryListAdapter {

    private SelectedContactsListener mSelectedContactsListener;
    private DeleteContactListener mDeleteContactListener;
    private TreeSet<Long> mSelectedContactIds = new TreeSet<>();
    private boolean mDisplayCheckBoxes;
    private final int mContactIdColumnIndex;

    public interface SelectedContactsListener {
        void onSelectedContactsChanged();
    }

    public interface DeleteContactListener {
        void onContactDeleteClicked(int position);
    }

    /**
     * @param contactIdColumnIndex the column index of the contact ID in the underlying cursor;
     *         it is passed in so that this adapter can support different kinds of contact
     *         lists (e.g. aggregate contacts or raw contacts).
     */
    public MultiSelectEntryContactListAdapter(Context context, int contactIdColumnIndex) {
        super(context);
        mContactIdColumnIndex = contactIdColumnIndex;
    }

    /**
     * Returns the column index of the contact ID in the underlying cursor; the contact ID
     * retrieved using this index is the value that is selected by this adapter (and returned
     * by {@link #getSelectedContactIds}).
     */
    public int getContactColumnIdIndex() {
        return mContactIdColumnIndex;
    }

    public DeleteContactListener getDeleteContactListener() {
        return mDeleteContactListener;
    }

    public void setDeleteContactListener(DeleteContactListener deleteContactListener) {
        mDeleteContactListener = deleteContactListener;
    }

    public void setSelectedContactsListener(SelectedContactsListener listener) {
        mSelectedContactsListener = listener;
    }

    /**
     * Returns set of selected contacts.
     */
    public TreeSet<Long> getSelectedContactIds() {
        return mSelectedContactIds;
    }

    public boolean hasSelectedItems() {
        return mSelectedContactIds.size() > 0;
    }

    /**
     * Returns the selected contacts as an array.
     */
    public long[] getSelectedContactIdsArray() {
        return GroupUtil.convertLongSetToLongArray(mSelectedContactIds);
    }

    /**
     * Update set of selected contacts. This changes which checkboxes are set.
     */
    public void setSelectedContactIds(TreeSet<Long> selectedContactIds) {
        this.mSelectedContactIds = selectedContactIds;
        notifyDataSetChanged();
        if (mSelectedContactsListener != null) {
            mSelectedContactsListener.onSelectedContactsChanged();
        }
    }

    /**
     * Shows checkboxes beside contacts if {@param displayCheckBoxes} is {@code TRUE}.
     * Not guaranteed to work with all configurations of this adapter.
     */
    public void setDisplayCheckBoxes(boolean showCheckBoxes) {
        mDisplayCheckBoxes = showCheckBoxes;
        notifyDataSetChanged();
        if (mSelectedContactsListener != null) {
            mSelectedContactsListener.onSelectedContactsChanged();
        }
    }

    /**
     * Checkboxes are being displayed beside contacts.
     */
    public boolean isDisplayingCheckBoxes() {
        return mDisplayCheckBoxes;
    }

    /**
     * Toggle the checkbox beside the contact for {@param contactId}.
     */
    public void toggleSelectionOfContactId(long contactId) {
        if (mSelectedContactIds.contains(contactId)) {
            mSelectedContactIds.remove(contactId);
        } else {
            mSelectedContactIds.add(contactId);
        }
        notifyDataSetChanged();
        if (mSelectedContactsListener != null) {
            mSelectedContactsListener.onSelectedContactsChanged();
        }
    }

    @Override
    public long getItemId(int position) {
        Cursor cursor = (Cursor) getItem(position);
        if (cursor != null) {
            return cursor.getLong(getContactColumnIdIndex());
        }
        return 0;
    }

    @Override
    protected void bindView(View itemView, int partition, Cursor cursor, int position) {
        super.bindView(itemView, partition, cursor, position);
        final ContactListItemView view = (ContactListItemView) itemView;
        bindViewId(view, cursor, getContactColumnIdIndex());
        bindCheckBox(view, cursor, partition == ContactsContract.Directory.DEFAULT);
    }

    /**
      * Loads the photo for the photo view.
      * @param photoIdColumn Index of the photo id column
      * @param lookUpKeyColumn Index of the lookup key column
      * @param displayNameColumn Index of the display name column
      */
    protected void bindPhoto(final ContactListItemView view, final Cursor cursor,
           final int photoIdColumn, final int lookUpKeyColumn, final int displayNameColumn) {
        final long photoId = cursor.isNull(photoIdColumn)
            ? 0 : cursor.getLong(photoIdColumn);
        final ContactPhotoManager.DefaultImageRequest imageRequest = photoId == 0
            ? getDefaultImageRequestFromCursor(cursor, displayNameColumn,
            lookUpKeyColumn)
            : null;
        getPhotoLoader().loadThumbnail(view.getPhotoView(), photoId, false, getCircularPhotos(),
                imageRequest);
    }

    private void bindCheckBox(ContactListItemView view, Cursor cursor, boolean isLocalDirectory) {
        // Disable clicking on all contacts from remote directories when showing check boxes. We do
        // this by telling the view to handle clicking itself.
        view.setClickable(!isLocalDirectory && mDisplayCheckBoxes);
        // Only show checkboxes if mDisplayCheckBoxes is enabled. Also, never show the
        // checkbox for other directory contacts except local directory.
        if (!mDisplayCheckBoxes || !isLocalDirectory) {
            view.hideCheckBox();
            return;
        }
        final CheckBox checkBox = view.getCheckBox();
        final long contactId = cursor.getLong(mContactIdColumnIndex);
        checkBox.setChecked(mSelectedContactIds.contains(contactId));
        checkBox.setClickable(false);
        checkBox.setTag(contactId);
    }
}
