/*
 * Copyright (C) 2016 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.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListPopupWindow;
import android.widget.TextView;

import com.android.contacts.R;
import com.android.contacts.model.account.AccountInfo;
import com.android.contacts.model.account.AccountWithDataSet;
import com.android.contacts.util.AccountsListAdapter;
import com.android.contacts.util.UiClosables;

import java.util.List;

/**
 * Controls the display of an account selector or header.
 *
 * TODO: This was mostly copied from {@link RawContactEditorView}. The code in that class
 * should probably be modified to use this instead of leaving it duplicated.
 */
public class AccountHeaderPresenter {

    private static final String KEY_SELECTED_ACCOUNT = "accountHeaderSelectedAccount";

    public interface Observer {
        void onChange(AccountHeaderPresenter sender);

        public static final Observer NONE = new Observer() {
            @Override
            public void onChange(AccountHeaderPresenter sender) {
            }
        };
    }

    private final Context mContext;

    private List<AccountInfo> mAccounts;
    private AccountWithDataSet mCurrentAccount;

    // Account header
    private final View mAccountHeaderContainer;
    private TextView mAccountHeaderType;
    private TextView mAccountHeaderName;
    private ImageView mAccountHeaderIcon;
    private ImageView mAccountHeaderExpanderIcon;

    // This would be different if the account was readonly
    @StringRes
    private int mSelectorTitle = R.string.editor_account_selector_title;

    private Observer mObserver = Observer.NONE;

    public AccountHeaderPresenter(View container) {
        mContext = container.getContext();
        mAccountHeaderContainer = container;
        // mAccountHeaderType is optional and may not be in the container view in which case
        // the variable will be null
        mAccountHeaderType = (TextView) container.findViewById(R.id.account_type);
        mAccountHeaderName = (TextView) container.findViewById(R.id.account_name);
        mAccountHeaderIcon = (ImageView) container.findViewById(R.id.account_type_icon);
        mAccountHeaderExpanderIcon = (ImageView) container.findViewById(R.id.account_expander_icon);
    }

    public void setObserver(Observer observer) {
        mObserver = observer;
    }

    public void setCurrentAccount(@NonNull AccountWithDataSet account) {
        if (mCurrentAccount != null && mCurrentAccount.equals(account)) {
            return;
        }
        mCurrentAccount = account;
        if (mObserver != null) {
            mObserver.onChange(this);
        }
        updateDisplayedAccount();
    }

    public void setAccounts(List<AccountInfo> accounts) {
        mAccounts = accounts;
        // If the current account hasn't been set or it has been removed just use the first
        // account.
        if (mCurrentAccount == null || !AccountInfo.contains(mAccounts, mCurrentAccount)) {
            mCurrentAccount = mAccounts.isEmpty() ? null : accounts.get(0).getAccount();
            mObserver.onChange(this);
        }
        updateDisplayedAccount();
    }

    public AccountWithDataSet getCurrentAccount() {
        return mCurrentAccount != null ? mCurrentAccount : null;
    }

    public void onSaveInstanceState(Bundle outState) {
        outState.putParcelable(KEY_SELECTED_ACCOUNT, mCurrentAccount);
    }

    public void onRestoreInstanceState(Bundle savedInstanceState) {
        if (savedInstanceState == null) return;
        if (mCurrentAccount == null) {
            mCurrentAccount = savedInstanceState.getParcelable(KEY_SELECTED_ACCOUNT);
        }
        updateDisplayedAccount();
    }

    private void updateDisplayedAccount() {
        mAccountHeaderContainer.setVisibility(View.GONE);
        if (mCurrentAccount == null) return;
        if (mAccounts == null) return;

        final String accountLabel = getAccountLabel(mCurrentAccount);

        if (mAccounts.size() > 1) {
            addAccountSelector(accountLabel);
        } else {
            addAccountHeader(accountLabel);
        }
    }

    private void addAccountHeader(String accountLabel) {
        mAccountHeaderContainer.setVisibility(View.VISIBLE);

        // Set the account name
        mAccountHeaderName.setVisibility(View.VISIBLE);
        mAccountHeaderName.setText(accountLabel);

        // Set the account type
        final String selectorTitle = mContext.getResources().getString(mSelectorTitle);
        if (mAccountHeaderType != null) {
            mAccountHeaderType.setText(selectorTitle);
        }

        final AccountInfo accountInfo = AccountInfo.getAccount(mAccounts, mCurrentAccount);

        // Set the icon
        mAccountHeaderIcon.setImageDrawable(accountInfo.getIcon());

        // Set the content description
        mAccountHeaderContainer.setContentDescription(
                EditorUiUtils.getAccountInfoContentDescription(accountLabel,
                        selectorTitle));
    }

    private void addAccountSelector(CharSequence nameLabel) {
        final View.OnClickListener onClickListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showPopup();
            }
        };
        setUpAccountSelector(nameLabel.toString(), onClickListener);
    }

    private void showPopup() {
        final ListPopupWindow popup = new ListPopupWindow(mContext);
        final AccountsListAdapter adapter =
                new AccountsListAdapter(mContext, mAccounts, mCurrentAccount);
        popup.setWidth(mAccountHeaderContainer.getWidth());
        popup.setAnchorView(mAccountHeaderContainer);
        popup.setAdapter(adapter);
        popup.setModal(true);
        popup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
        popup.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position,
                    long id) {
                UiClosables.closeQuietly(popup);
                final AccountWithDataSet newAccount = adapter.getItem(position);
                setCurrentAccount(newAccount);
                // Make sure the new selection will be announced once it's changed
                mAccountHeaderContainer.setAccessibilityLiveRegion(
                        View.ACCESSIBILITY_LIVE_REGION_POLITE);
            }
        });
        mAccountHeaderContainer.post(new Runnable() {
            @Override
            public void run() {
                popup.show();
            }
        });
    }

    private void setUpAccountSelector(String nameLabel, View.OnClickListener listener) {
        addAccountHeader(nameLabel);
        // Add handlers for choosing another account to save to.
        mAccountHeaderExpanderIcon.setVisibility(View.VISIBLE);
        // Add the listener to the icon so that it will be announced by talkback as a clickable
        // element
        mAccountHeaderExpanderIcon.setOnClickListener(listener);
        mAccountHeaderContainer.setOnClickListener(listener);
    }

    private String getAccountLabel(AccountWithDataSet account) {
        final AccountInfo accountInfo = AccountInfo.getAccount(mAccounts, account);
        return accountInfo != null ? accountInfo.getNameLabel().toString() : null;
    }
}
