/*
 * 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.editors.layout.refactoring;

import static com.android.SdkConstants.FQCN_GESTURE_OVERLAY_VIEW;
import static com.android.SdkConstants.FQCN_LINEAR_LAYOUT;
import static com.android.SdkConstants.FQCN_RADIO_BUTTON;
import static com.android.SdkConstants.GESTURE_OVERLAY_VIEW;
import static com.android.SdkConstants.RADIO_GROUP;
import static com.android.SdkConstants.VIEW_INCLUDE;

import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.CustomViewFinder;
import com.android.ide.eclipse.adt.internal.editors.layout.gre.PaletteMetadataDescriptor;
import com.android.ide.eclipse.adt.internal.editors.layout.gre.ViewMetadataRepository;
import com.android.ide.eclipse.adt.internal.resources.ResourceNameValidator;
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.resources.ResourceType;
import com.android.sdklib.IAndroidTarget;
import com.android.utils.Pair;

import org.eclipse.core.resources.IProject;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

public class WrapInWizard extends VisualRefactoringWizard {
    private static final String SEPARATOR_LABEL =
        "----------------------------------------"; //$NON-NLS-1$

    public WrapInWizard(WrapInRefactoring ref, LayoutEditorDelegate editor) {
        super(ref, editor);
        setDefaultPageTitle("Wrap in Container");
    }

    @Override
    protected void addUserInputPages() {
        WrapInRefactoring ref = (WrapInRefactoring) getRefactoring();
        String oldType = ref.getOldType();
        addPage(new InputPage(mDelegate.getEditor().getProject(), oldType));
    }

    /** Wizard page which inputs parameters for the {@link WrapInRefactoring} operation */
    private static class InputPage extends VisualRefactoringInputPage {
        private final IProject mProject;
        private final String mOldType;
        private Text mIdText;
        private Combo mTypeCombo;
        private List<Pair<String, ViewElementDescriptor>> mClassNames;

        public InputPage(IProject project, String oldType) {
            super("WrapInInputPage");  //$NON-NLS-1$
            mProject = project;
            mOldType = oldType;
        }

        @Override
        public void createControl(Composite parent) {
            Composite composite = new Composite(parent, SWT.NONE);
            composite.setLayout(new GridLayout(2, false));

            Label typeLabel = new Label(composite, SWT.NONE);
            typeLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
            typeLabel.setText("Type of Container:");

            mTypeCombo = new Combo(composite, SWT.READ_ONLY);
            mTypeCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
            mTypeCombo.addSelectionListener(mSelectionValidateListener);

            Label idLabel = new Label(composite, SWT.NONE);
            idLabel.setText("New Layout Id:");
            idLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));

            mIdText = new Text(composite, SWT.BORDER);
            mIdText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
            mIdText.addModifyListener(mModifyValidateListener);

            Set<String> exclude = Collections.singleton(VIEW_INCLUDE);
            mClassNames = addLayouts(mProject, mOldType, mTypeCombo, exclude, true);
            mTypeCombo.select(0);

            setControl(composite);
            validatePage();

            mTypeCombo.setFocus();
        }

        @Override
        protected boolean validatePage() {
            boolean ok = true;

            String id = mIdText.getText().trim();

            if (id.length() == 0) {
                setErrorMessage("ID required");
                ok = false;
            } else {
                // ...but if you do, it has to be valid!
                ResourceNameValidator validator = ResourceNameValidator.create(false, mProject,
                        ResourceType.ID);
                String message = validator.isValid(id);
                if (message != null) {
                    setErrorMessage(message);
                    ok = false;
                }
            }

            int selectionIndex = mTypeCombo.getSelectionIndex();
            String type = selectionIndex != -1 ? mClassNames.get(selectionIndex).getFirst() : null;
            if (type == null) {
                setErrorMessage("Select a container type");
                ok = false; // The user has chosen a separator
            }

            if (ok) {
                setErrorMessage(null);

                // Record state
                WrapInRefactoring refactoring =
                    (WrapInRefactoring) getRefactoring();
                refactoring.setId(id);
                refactoring.setType(type);

                ViewElementDescriptor descriptor = mClassNames.get(selectionIndex).getSecond();
                if (descriptor instanceof PaletteMetadataDescriptor) {
                    PaletteMetadataDescriptor paletteDescriptor =
                        (PaletteMetadataDescriptor) descriptor;
                    String initializedAttributes = paletteDescriptor.getInitializedAttributes();
                    refactoring.setInitializedAttributes(initializedAttributes);
                } else {
                    refactoring.setInitializedAttributes(null);
                }
            }

            setPageComplete(ok);
            return ok;
        }
    }

    static List<Pair<String, ViewElementDescriptor>> addLayouts(IProject project,
            String oldType, Combo combo,
            Set<String> exclude, boolean addGestureOverlay) {
        List<Pair<String, ViewElementDescriptor>> classNames =
            new ArrayList<Pair<String, ViewElementDescriptor>>();

        if (oldType != null && oldType.equals(FQCN_RADIO_BUTTON)) {
            combo.add(RADIO_GROUP);
            // NOT a fully qualified name since android widgets do not include the package
            classNames.add(Pair.of(RADIO_GROUP, (ViewElementDescriptor) null));

            combo.add(SEPARATOR_LABEL);
            classNames.add(Pair.<String,ViewElementDescriptor>of(null, null));
        }

        Pair<List<String>,List<String>> result = CustomViewFinder.findViews(project, true);
        List<String> customViews = result.getFirst();
        List<String> thirdPartyViews = result.getSecond();
        if (customViews.size() > 0) {
            for (String view : customViews) {
                combo.add(view);
                classNames.add(Pair.of(view, (ViewElementDescriptor) null));
            }
            combo.add(SEPARATOR_LABEL);
            classNames.add(Pair.<String,ViewElementDescriptor>of(null, null));
        }

        // Populate type combo
        Sdk currentSdk = Sdk.getCurrent();
        if (currentSdk != null) {
            IAndroidTarget target = currentSdk.getTarget(project);
            if (target != null) {
                AndroidTargetData targetData = currentSdk.getTargetData(target);
                if (targetData != null) {
                    ViewMetadataRepository repository = ViewMetadataRepository.get();
                    List<Pair<String,List<ViewElementDescriptor>>> entries =
                        repository.getPaletteEntries(targetData, false, true);
                    // Find the layout category - it contains LinearLayout
                    List<ViewElementDescriptor> layoutDescriptors = null;

                    search: for (Pair<String,List<ViewElementDescriptor>> pair : entries) {
                        List<ViewElementDescriptor> list = pair.getSecond();
                        for (ViewElementDescriptor d : list) {
                            if (d.getFullClassName().equals(FQCN_LINEAR_LAYOUT)) {
                                // Found - use this list
                                layoutDescriptors = list;
                                break search;
                            }
                        }
                    }
                    if (layoutDescriptors != null) {
                        for (ViewElementDescriptor d : layoutDescriptors) {
                            String className = d.getFullClassName();
                            if (exclude == null || !exclude.contains(className)) {
                                combo.add(d.getUiName());
                                classNames.add(Pair.of(className, d));
                            }
                        }

                        // SWT does not support separators in combo boxes
                        combo.add(SEPARATOR_LABEL);
                        classNames.add(null);

                        if (thirdPartyViews.size() > 0) {
                            for (String view : thirdPartyViews) {
                                combo.add(view);
                                classNames.add(Pair.of(view, (ViewElementDescriptor) null));
                            }
                            combo.add(SEPARATOR_LABEL);
                            classNames.add(null);
                        }

                        if (addGestureOverlay) {
                            combo.add(GESTURE_OVERLAY_VIEW);
                            classNames.add(Pair.<String, ViewElementDescriptor> of(
                                    FQCN_GESTURE_OVERLAY_VIEW, null));

                            combo.add(SEPARATOR_LABEL);
                            classNames.add(Pair.<String,ViewElementDescriptor>of(null, null));
                        }
                    }

                    // Now add ALL known layout descriptors in case the user has
                    // a special case
                    layoutDescriptors =
                        targetData.getLayoutDescriptors().getLayoutDescriptors();

                    for (ViewElementDescriptor d : layoutDescriptors) {
                        String className = d.getFullClassName();
                        if (exclude == null || !exclude.contains(className)) {
                            combo.add(d.getUiName());
                            classNames.add(Pair.of(className, d));
                        }
                    }
                }
            }
        } else {
            combo.add("SDK not initialized");
            classNames.add(Pair.<String,ViewElementDescriptor>of(null, null));
        }

        return classNames;
    }
}
