/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
 *
 * 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.ide.eclipse.adt.internal.wizards.newproject;

import com.android.ide.common.xml.ManifestData;
import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
import com.android.ide.eclipse.adt.internal.project.ProjectChooserHelper;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.sdklib.IAndroidTarget;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.ui.JavaElementLabelProvider;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.dialogs.FilteredList;

/**
 * Page shown when creating a test project which lets you choose between testing
 * yourself and testing a different project
 */
class TestTargetPage extends WizardPage implements SelectionListener {
    private final NewProjectWizardState mValues;
    /** Flag used when setting button/text state manually to ignore listener updates */
    private boolean mIgnore;
    private String mLastExistingPackageName;

    private Button mCurrentRadioButton;
    private Button mExistingRadioButton;
    private FilteredList mProjectList;
    private boolean mPageShown;

    /**
     * Create the wizard.
     */
    TestTargetPage(NewProjectWizardState values) {
        super("testTargetPage"); //$NON-NLS-1$
        setTitle("Select Test Target");
        setDescription("Choose a project to test");
        mValues = values;
    }

    /**
     * Create contents of the wizard.
     */
    @Override
    public void createControl(Composite parent) {
        Composite container = new Composite(parent, SWT.NULL);

        setControl(container);
        container.setLayout(new GridLayout(2, false));

        mCurrentRadioButton = new Button(container, SWT.RADIO);
        mCurrentRadioButton.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
        mCurrentRadioButton.setText("This project");
        mCurrentRadioButton.addSelectionListener(this);

        mExistingRadioButton = new Button(container, SWT.RADIO);
        mExistingRadioButton.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
        mExistingRadioButton.setText("An existing Android project:");
        mExistingRadioButton.addSelectionListener(this);

        ILabelProvider labelProvider = new JavaElementLabelProvider(
                JavaElementLabelProvider.SHOW_DEFAULT);
        mProjectList = new FilteredList(container,
                SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.SINGLE, labelProvider,
                true /*ignoreCase*/, false /*allowDuplicates*/, true /* matchEmptyString*/);
        mProjectList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
        mProjectList.addSelectionListener(this);
    }

    private void initializeList() {
        ProjectChooserHelper helper = new ProjectChooserHelper(getShell(), null /*filter*/);
        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
        IJavaModel javaModel = JavaCore.create(workspaceRoot);
        IJavaProject[] androidProjects = helper.getAndroidProjects(javaModel);
        mProjectList.setElements(androidProjects);
        if (mValues.testedProject != null) {
            for (IJavaProject project : androidProjects) {
                if (project.getProject() == mValues.testedProject) {
                    mProjectList.setSelection(new Object[] { project });
                    break;
                }
            }
        } else {
            // No initial selection: force the user to choose
            mProjectList.setSelection(new int[0]);
        }
    }

    @Override
    public void setVisible(boolean visible) {
        super.setVisible(visible);
        mPageShown = true;

        if (visible) {
            try {
                mIgnore = true;
                mCurrentRadioButton.setSelection(mValues.testingSelf);
                mExistingRadioButton.setSelection(!mValues.testingSelf);
                mProjectList.setEnabled(!mValues.testingSelf);

                if (mProjectList.isEmpty()) {
                    initializeList();
                }
                if (!mValues.testingSelf) {
                    mProjectList.setFocus();
                    IProject project = getSelectedProject();
                    if (project != null) {
                        // The FilteredList seems to -insist- on selecting the first item
                        // in the list, even when the selection is explicitly set to an empty
                        // array. This means the user is looking at a selection, so we need
                        // to also go ahead and select this item in the model such that the
                        // two agree, even if we would have preferred to have no initial
                        // selection.
                        mValues.testedProject = project;
                    }
                }
            } finally {
                mIgnore = false;
            }
        }

        validatePage();
    }

    @Override
    public void widgetSelected(SelectionEvent e) {
        if (mIgnore) {
            return;
        }

        Object source = e.getSource();
        if (source == mExistingRadioButton) {
            mProjectList.setEnabled(true);
            mValues.testingSelf = false;
            setExistingProject(getSelectedProject());
            mProjectList.setFocus();
        } else if (source == mCurrentRadioButton) {
            mProjectList.setEnabled(false);
            mValues.testingSelf = true;
            mValues.testedProject = null;
        } else {
            // The event must be from the project list, which unfortunately doesn't
            // pass itself as the selection event, it passes a reference to some internal
            // table widget that it uses, so we check for this case last
            IProject project = getSelectedProject();
            if (project != mValues.testedProject) {
                setExistingProject(project);
            }
        }

        validatePage();
    }

    private IProject getSelectedProject() {
        Object[] selection = mProjectList.getSelection();
        IProject project = selection != null && selection.length == 1
            ? ((IJavaProject) selection[0]).getProject() : null;
        return project;
    }

    @Override
    public void widgetDefaultSelected(SelectionEvent e) {
    }

    private void setExistingProject(IProject project) {
        mValues.testedProject = project;

        // Try to update the application, package, sdk target and minSdkVersion accordingly
        if (project != null &&
                (!mValues.applicationNameModifiedByUser ||
                 !mValues.packageNameModifiedByUser     ||
                 !mValues.targetModifiedByUser          ||
                 !mValues.minSdkModifiedByUser)) {
            ManifestData manifestData = AndroidManifestHelper.parseForData(project);
            if (manifestData != null) {
                String appName = String.format("%1$sTest", project.getName());
                String packageName = manifestData.getPackage();
                String minSdkVersion = manifestData.getMinSdkVersionString();
                IAndroidTarget sdkTarget = null;
                if (Sdk.getCurrent() != null) {
                    sdkTarget = Sdk.getCurrent().getTarget(project);
                }

                if (packageName == null) {
                    packageName = "";  //$NON-NLS-1$
                }
                mLastExistingPackageName = packageName;

                if (!mValues.projectNameModifiedByUser) {
                    mValues.projectName = appName;
                }

                if (!mValues.applicationNameModifiedByUser) {
                    mValues.applicationName = appName;
                }

                if (!mValues.packageNameModifiedByUser) {
                    packageName += ".test";  //$NON-NLS-1$
                    mValues.packageName = packageName;
                }

                if (!mValues.targetModifiedByUser && sdkTarget != null) {
                    mValues.target = sdkTarget;
                }

                if (!mValues.minSdkModifiedByUser) {
                    if (minSdkVersion != null || sdkTarget != null) {
                        mValues.minSdk = minSdkVersion;
                    }
                    if (sdkTarget == null) {
                        mValues.updateSdkTargetToMatchMinSdkVersion();
                    }
                }
            }
        }

        updateTestTargetPackageField(mLastExistingPackageName);
    }

    /**
     * Updates the test target package name
     *
     * When using the "self-test" option, the packageName argument is ignored and the
     * current value from the project package is used.
     *
     * Otherwise the packageName is used if it is not null.
     */
    private void updateTestTargetPackageField(String packageName) {
        if (mValues.testingSelf) {
            mValues.testTargetPackageName = mValues.packageName;
        } else if (packageName != null) {
            mValues.testTargetPackageName = packageName;
        }
    }

    @Override
    public boolean isPageComplete() {
        // Ensure that the user sees the page and makes a selection
        if (!mPageShown) {
            return false;
        }

        return super.isPageComplete();
    }

    private void validatePage() {
        String error = null;

        if (!mValues.testingSelf) {
            if (mValues.testedProject == null) {
                error = "Please select an existing Android project as a test target.";
            } else if (mValues.projectName.equals(mValues.testedProject.getName())) {
                error = "The main project name and the test project name must be different.";
            }
        }

        // -- update UI & enable finish if there's no error
        setPageComplete(error == null);
        if (error != null) {
            setMessage(error, IMessageProvider.ERROR);
        } else {
            setErrorMessage(null);
            setMessage(null);
        }
    }
}
