/*
 * 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 was removed just switch to the next one in the list.
        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;
    }
}
