// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.chrome.browser.tabmodel;

import android.app.Activity;

import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.ObserverList;
import org.chromium.chrome.browser.Tab;
import org.chromium.chrome.browser.profiles.Profile;

/**
 * Simple TabModel that assumes that only one Tab exists.
 */
public class SingleTabModel implements TabModel {
    private final Activity mActivity;
    private final ObserverList<TabModelObserver> mObservers = new ObserverList<TabModelObserver>();

    private Tab mTab;
    private boolean mIsIncognito;
    private boolean mBlockNewWindows;

    SingleTabModel(Activity activity, boolean incognito, boolean blockNewWindows) {
        mActivity = activity;
        mIsIncognito = incognito;
        mBlockNewWindows = blockNewWindows;
    }

    /**
     * Sets the Tab that is managed by the SingleTabModel.
     * Should only be called once.
     * @param tab Tab to manage.
     */
    void setTab(Tab tab) {
        mTab = tab;
        assert mTab.isIncognito() == mIsIncognito;
        if (mBlockNewWindows) nativePermanentlyBlockAllNewWindows(mTab);

        for (TabModelObserver observer : mObservers) {
            observer.didAddTab(tab, TabLaunchType.FROM_LINK);
        }
    }

    @Override
    public Profile getProfile() {
        return mTab.getProfile();
    }

    @Override
    public boolean isIncognito() {
        return mIsIncognito;
    }

    @Override
    public int getCount() {
        return mTab == null ? 0 : 1;
    }

    @Override
    public int indexOf(Tab tab) {
        return mTab != null && mTab.getId() == tab.getId() ? 0 : INVALID_TAB_INDEX;
    }

    @Override
    public int index() {
        return 0;
    }

    @Override
    public boolean closeTab(Tab tab) {
        return closeTab(tab, false, false, false);
    }

    @Override
    public boolean closeTab(Tab tab, boolean animate, boolean uponExit, boolean canUndo) {
        if (mTab != null && mTab.getId() == tab.getId()) {
            completeActivity();
            return true;
        }
        return false;
    }

    /**
     * In webapps, calls finish on the activity, but keeps it in recents. In Document mode,
     * finishes and removes from recents. We use mBlockNewWindows flag to distinguish the user
     * of this model.
     */
    private void completeActivity() {
        if (mBlockNewWindows) {
            mActivity.finish();
        } else {
            ApiCompatibilityUtils.finishAndRemoveTask(mActivity);
        }
    }

    @Override
    public void closeAllTabs() {
        closeAllTabs(true, false);
    }

    @Override
    public void closeAllTabs(boolean allowDelegation, boolean uponExit) {
        completeActivity();
    }

    // Tab retrieval functions.
    @Override
    public Tab getTabAt(int position) {
        return position == 0 ? mTab : null;
    }

    @Override
    public void setIndex(int i, final TabSelectionType type) {
        assert i == 0;
    }

    @Override
    public void moveTab(int id, int newIndex) {
        assert false;
    }

    @Override
    public Tab getNextTabIfClosed(int id) {
        return null;
    }

    @Override
    public boolean isClosurePending(int tabId) {
        return false;
    }

    @Override
    public TabList getComprehensiveModel() {
        return this;
    }

    @Override
    public void commitAllTabClosures() {
    }

    @Override
    public void commitTabClosure(int tabId) {
    }

    @Override
    public void cancelTabClosure(int tabId) {
    }

    @Override
    public boolean supportsPendingClosures() {
        return false;
    }

    @Override
    public void addTab(Tab tab, int index, TabLaunchType type) {
    }

    @Override
    public void addObserver(TabModelObserver observer) {
        mObservers.addObserver(observer);
    }

    @Override
    public void removeObserver(TabModelObserver observer) {
        mObservers.removeObserver(observer);
    }

    // Below are functions that are overridden but should be moved out of TabModel.
    @Override
    public void destroy() {
    }

    private static native void nativePermanentlyBlockAllNewWindows(Tab nativeTabAndroid);

}

@@ -262,35 +262,119 @@
 m.base.A
-piCompatibilityUtil
+ctivityState;%0Aimport org.chromium.base.ApiCompatibilityUtils;%0Aimport org.chromium.base.ApplicationStatu
 s;%0Aimpor
@@ -1483,32 +1483,294 @@
 LINK);%0A        %7D
+%0A%0A        int state = ApplicationStatus.getStateForActivity(mActivity);%0A        if (state == ActivityState.CREATED %7C%7C state == ActivityState.STARTED%0A                %7C%7C state == ActivityState.RESUMED) %7B%0A            mTab.show(TabSelectionType.FROM_USER);%0A        %7D
 %0A    %7D%0A%0A    @Ove

Make SingleTabModel show() its Tab