/*
 * 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 org.eclipse.jface.viewers.StyledString.DECORATIONS_STYLER;
import static org.eclipse.jface.viewers.StyledString.QUALIFIER_STYLER;

import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
import com.android.ide.eclipse.adt.internal.resources.ResourceNameValidator;
import com.android.resources.ResourceType;
import com.android.utils.Pair;

import org.eclipse.core.resources.IProject;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Text;
import org.w3c.dom.Attr;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

class ExtractStyleWizard extends VisualRefactoringWizard {
    public ExtractStyleWizard(ExtractStyleRefactoring ref, LayoutEditorDelegate editor) {
        super(ref, editor);
        setDefaultPageTitle(ref.getName());
    }

    @Override
    protected void addUserInputPages() {
        String initialName = "styleName";
        addPage(new InputPage(mDelegate.getEditor().getProject(), initialName));
    }

    /**
     * Wizard page which inputs parameters for the {@link ExtractStyleRefactoring}
     * operation
     */
    private static class InputPage extends VisualRefactoringInputPage {
        private final IProject mProject;
        private final String mSuggestedName;
        private Text mNameText;
        private Table mTable;
        private Button mRemoveExtracted;
        private Button mSetStyle;
        private Button mRemoveAll;
        private Button mExtend;
        private CheckboxTableViewer mCheckedView;

        private String mParentStyle;
        private Set<Attr> mInSelection;
        private List<Attr> mAllAttributes;
        private int mElementCount;
        private Map<Attr, Integer> mFrequencyCount;
        private Set<Attr> mShown;
        private List<Attr> mInitialChecked;
        private List<Attr> mAllChecked;
        private List<Map.Entry<String, List<Attr>>> mRoot;
        private Map<String, List<Attr>> mAvailableAttributes;

        public InputPage(IProject project, String suggestedName) {
            super("ExtractStyleInputPage");
            mProject = project;
            mSuggestedName = suggestedName;
        }

        @Override
        public void createControl(Composite parent) {
            initialize();

            Composite composite = new Composite(parent, SWT.NONE);
            composite.setLayout(new GridLayout(2, false));

            Label nameLabel = new Label(composite, SWT.NONE);
            nameLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
            nameLabel.setText("Style Name:");

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

            mRemoveExtracted = new Button(composite, SWT.CHECK);
            mRemoveExtracted.setSelection(true);
            mRemoveExtracted.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 2, 1));
            mRemoveExtracted.setText("Remove extracted attributes");
            mRemoveExtracted.addSelectionListener(mSelectionValidateListener);

            mRemoveAll = new Button(composite, SWT.CHECK);
            mRemoveAll.setSelection(false);
            mRemoveAll.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 2, 1));
            mRemoveAll.setText("Remove all extracted attributes regardless of value");
            mRemoveAll.addSelectionListener(mSelectionValidateListener);

            boolean defaultSetStyle = false;
            if (mParentStyle != null) {
                mExtend = new Button(composite, SWT.CHECK);
                mExtend.setSelection(true);
                mExtend.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 2, 1));
                mExtend.setText(String.format("Extend %1$s", mParentStyle));
                mExtend.addSelectionListener(mSelectionValidateListener);
                defaultSetStyle = true;
            }

            mSetStyle = new Button(composite, SWT.CHECK);
            mSetStyle.setSelection(defaultSetStyle);
            mSetStyle.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 2, 1));
            mSetStyle.setText("Set style attribute on extracted elements");
            mSetStyle.addSelectionListener(mSelectionValidateListener);

            new Label(composite, SWT.NONE);
            new Label(composite, SWT.NONE);

            Label tableLabel = new Label(composite, SWT.NONE);
            tableLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
            tableLabel.setText("Choose style attributes to extract:");

            mCheckedView = CheckboxTableViewer.newCheckList(composite, SWT.BORDER
                    | SWT.FULL_SELECTION | SWT.HIDE_SELECTION);
            mTable = mCheckedView.getTable();
            mTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 2));
            ((GridData) mTable.getLayoutData()).heightHint = 200;

            mCheckedView.setContentProvider(new ArgumentContentProvider());
            mCheckedView.setLabelProvider(new ArgumentLabelProvider());
            mCheckedView.setInput(mRoot);
            final Object[] initialSelection = mInitialChecked.toArray();
            mCheckedView.setCheckedElements(initialSelection);

            mCheckedView.addCheckStateListener(new ICheckStateListener() {
                @Override
                public void checkStateChanged(CheckStateChangedEvent event) {
                    // Try to disable other elements that conflict with this
                    boolean isChecked = event.getChecked();
                    if (isChecked) {
                        Attr attribute = (Attr) event.getElement();
                        List<Attr> list = mAvailableAttributes.get(attribute.getLocalName());
                        for (Attr other : list) {
                            if (other != attribute && mShown.contains(other)) {
                                mCheckedView.setChecked(other, false);
                            }
                        }
                    }

                    validatePage();
                }
            });

            // Select All / Deselect All
            Composite buttonForm = new Composite(composite, SWT.NONE);
            buttonForm.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
            RowLayout rowLayout = new RowLayout(SWT.HORIZONTAL);
            rowLayout.marginTop = 0;
            rowLayout.marginLeft = 0;
            buttonForm.setLayout(rowLayout);
            Button checkAllButton = new Button(buttonForm, SWT.FLAT);
            checkAllButton.setText("Select All");
            checkAllButton.addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(SelectionEvent e) {
                    // Select "all" (but not conflicting settings)
                    mCheckedView.setCheckedElements(mAllChecked.toArray());
                    validatePage();
                }
            });
            Button uncheckAllButton = new Button(buttonForm, SWT.FLAT);
            uncheckAllButton.setText("Deselect All");
            uncheckAllButton.addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(SelectionEvent e) {
                    mCheckedView.setAllChecked(false);
                    validatePage();
                }
            });

            // Initialize UI:
            if (mSuggestedName != null) {
                mNameText.setText(mSuggestedName);
            }

            setControl(composite);
            validatePage();
        }

        private void initialize() {
            ExtractStyleRefactoring ref = (ExtractStyleRefactoring) getRefactoring();

            mElementCount = ref.getElements().size();

            mParentStyle = ref.getParentStyle();

            // Set up data structures needed by the wizard -- to compute the actual
            // attributes to list in the wizard (there could be multiple attributes
            // of the same name (on different elements) and we only want to show one, etc.)

            Pair<Map<String, List<Attr>>, Set<Attr>> result = ref.getAvailableAttributes();
            // List of all available attributes on the selected elements
            mAvailableAttributes = result.getFirst();
            // Set of attributes that overlap the text selection, or all attributes if
            // wizard is invoked from GUI context
            mInSelection = result.getSecond();

            // The root data structure, which we set as the table root. The content provider
            // will produce children from it. This is the entry set of a map from
            // attribute name to list of attribute nodes for that attribute name.
            mRoot = new ArrayList<Map.Entry<String, List<Attr>>>(
                mAvailableAttributes.entrySet());

            // Sort the items by attribute name -- the attribute name is the key
            // in the entry set above.
            Collections.sort(mRoot, new Comparator<Map.Entry<String, List<Attr>>>() {
                @Override
                public int compare(Map.Entry<String, List<Attr>> e1,
                        Map.Entry<String, List<Attr>> e2) {
                    return e1.getKey().compareTo(e2.getKey());
                }
            });

            // Set of attributes actually included in the list shown to the user.
            // (There could be many additional "aliasing" nodes on other elements
            // with the same name.) Note however that we DO show multiple attribute
            // occurrences of the same attribute name: precisely one for each unique -value-
            // of that attribute.
            mShown = new HashSet<Attr>();

            // The list of initially checked attributes.
            mInitialChecked = new ArrayList<Attr>();

            // The list of attributes to be checked if "Select All" is chosen (this is not
            // the same as *all* attributes, since we need to exclude any conflicts)
            mAllChecked = new ArrayList<Attr>();

            // All attributes.
            mAllAttributes = new ArrayList<Attr>();

            // Frequency count, from attribute to integer. Attributes that do not
            // appear in the list have frequency 1, not 0.
            mFrequencyCount = new HashMap<Attr, Integer>();

            for (Map.Entry<String, List<Attr>> entry : mRoot) {
                // Iterate over all attributes of the same name, and sort them
                // by value. This will make it easy to list each -unique- value in the
                // wizard.
                List<Attr> attrList = entry.getValue();
                Collections.sort(attrList, new Comparator<Attr>() {
                    @Override
                    public int compare(Attr a1, Attr a2) {
                        return a1.getValue().compareTo(a2.getValue());
                    }
                });

                // We need to compute a couple of things: the frequency for all identical
                // values (and stash them in the frequency map), and record the first
                // attribute with a particular value into the list of attributes to
                // be shown.
                Attr prevAttr = null;
                String prev = null;
                List<Attr> uniqueValueAttrs = new ArrayList<Attr>();
                for (Attr attr : attrList) {
                    String value = attr.getValue();
                    if (value.equals(prev)) {
                        Integer count = mFrequencyCount.get(prevAttr);
                        if (count == null) {
                            count = Integer.valueOf(2);
                        } else {
                            count = Integer.valueOf(count.intValue() + 1);
                        }
                        mFrequencyCount.put(prevAttr, count);
                    } else {
                        uniqueValueAttrs.add(attr);
                        prev = value;
                        prevAttr = attr;
                    }
                }

                // Sort the values by frequency (and for equal frequencies, alphabetically
                // by value)
                Collections.sort(uniqueValueAttrs, new Comparator<Attr>() {
                    @Override
                    public int compare(Attr a1, Attr a2) {
                        Integer f1 = mFrequencyCount.get(a1);
                        Integer f2 = mFrequencyCount.get(a2);
                        if (f1 == null) {
                            f1 = Integer.valueOf(1);
                        }
                        if (f2 == null) {
                            f2 = Integer.valueOf(1);
                        }
                        int delta = f2.intValue() - f1.intValue();
                        if (delta != 0) {
                            return delta;
                        } else {
                            return a1.getValue().compareTo(a2.getValue());
                        }
                    }
                });

                // Add the items in order, and select those attributes that overlap
                // the selection
                mAllAttributes.addAll(uniqueValueAttrs);
                mShown.addAll(uniqueValueAttrs);
                Attr first = uniqueValueAttrs.get(0);
                mAllChecked.add(first);
                if (mInSelection.contains(first)) {
                    mInitialChecked.add(first);
                }
            }
        }

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

            String text = mNameText.getText().trim();

            if (text.length() == 0) {
                setErrorMessage("Provide a name for the new style");
                ok = false;
            } else {
                ResourceNameValidator validator = ResourceNameValidator.create(false, mProject,
                        ResourceType.STYLE);
                String message = validator.isValid(text);
                if (message != null) {
                    setErrorMessage(message);
                    ok = false;
                }
            }

            Object[] checkedElements = mCheckedView.getCheckedElements();
            if (checkedElements.length == 0) {
                setErrorMessage("Choose at least one attribute to extract");
                ok = false;
            }

            if (ok) {
                setErrorMessage(null);

                // Record state
                ExtractStyleRefactoring refactoring = (ExtractStyleRefactoring) getRefactoring();
                refactoring.setStyleName(text);
                refactoring.setRemoveExtracted(mRemoveExtracted.getSelection());
                refactoring.setRemoveAll(mRemoveAll.getSelection());
                refactoring.setApplyStyle(mSetStyle.getSelection());
                if (mExtend != null && mExtend.getSelection()) {
                    refactoring.setParent(mParentStyle);
                }
                List<Attr> attributes = new ArrayList<Attr>();
                for (Object o : checkedElements) {
                    attributes.add((Attr) o);
                }
                refactoring.setChosenAttributes(attributes);
            }

            setPageComplete(ok);
            return ok;
        }

        private class ArgumentLabelProvider extends StyledCellLabelProvider {
            public ArgumentLabelProvider() {
            }

            @Override
            public void update(ViewerCell cell) {
                Object element = cell.getElement();
                Attr attribute = (Attr) element;

                StyledString styledString = new StyledString();
                styledString.append(attribute.getLocalName());
                styledString.append(" = ", QUALIFIER_STYLER);
                styledString.append(attribute.getValue());

                if (mElementCount > 1) {
                    Integer f = mFrequencyCount.get(attribute);
                    String s = String.format(" (in %d/%d elements)",
                            f != null ? f.intValue(): 1, mElementCount);
                    styledString.append(s, DECORATIONS_STYLER);
                }
                cell.setText(styledString.toString());
                cell.setStyleRanges(styledString.getStyleRanges());
                super.update(cell);
            }
        }

        private class ArgumentContentProvider implements IStructuredContentProvider {
            public ArgumentContentProvider() {
            }

            @Override
            public Object[] getElements(Object inputElement) {
                if (inputElement == mRoot) {
                    return mAllAttributes.toArray();
                }

                return new Object[0];
            }

            @Override
            public void dispose() {
            }

            @Override
            public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
            }
        }
    }
}
