/*******************************************************************************
 * Copyright (c) 2010 University of Illinois at Urbana-Champaign and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Abhishek Sharma, UIUC - Initial API and implementation
 *******************************************************************************/
package org.eclipse.rephraserengine.internal.ui.browser;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.rephraserengine.core.vpg.IVPGNode;
import org.eclipse.rephraserengine.core.vpg.VPGEdge;
import org.eclipse.rephraserengine.core.vpg.eclipse.EclipseVPG;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CaretEvent;
import org.eclipse.swt.custom.CaretListener;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
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.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;

/**
 * The Edges tab in the VPG Browser.
 * 
 * @author Abhishek Sharma
 */
class EdgesTab
{
    private TabItem edges;
    private Composite composite;
    private StyledText styledText;
    private Button showAll;
    private Button showSelected;
    private Button edgeButton ;
    private String filename;
    private List<VPGEdge<?,?,?>> edgesInFile;
    private Set<VPGEdge<?,?,?>> showEdges;
    private EclipseVPG vpg;
    private Set<Integer> edgeTypes;
    private Set<Integer> edgeTypesToShow;
    private List<Color> color ;
    private Label label;

    public EdgesTab(TabItem edges, TabFolder tabFolder, EclipseVPG vpg)
    {
        this.vpg = vpg ;
        this.filename = null;
        this.edgesInFile = Collections.emptyList();
        this.showEdges = Collections.emptySet();
        this.edges = edges;
        this.edgeTypes = Collections.emptySet();
        this.edgeTypesToShow = new HashSet<Integer>();
        this.color = Collections.emptyList();
       
        color = new ArrayList<Color>();
        addColors();
        createControls(tabFolder);   
    }

    /** Adds three new colors red,green and blue to the color list
     * 
     */
    private void addColors()
    {
        //Adds three new colors red,green and blue to the color list
        color.add(new Color(null, new RGB(192,0,0)));
        color.add(new Color(null, new RGB(0,192,0)));
        color.add(new Color(null, new RGB(0,0,192)));
    }

    private void createControls(TabFolder tabfolder)
    {
        createComposite(tabfolder);
        createRadioButtons();
        createEdgesMenu();
        createStyledText();
        createLabel();   
    }

   
    private void createLabel()
    {
        label= new Label(composite, SWT.NONE);
        label.setText(""); //$NON-NLS-1$
    }

    private void createEdgesMenu()
    {
        edgeButton = new Button(composite, SWT.FLAT);
        edgeButton.setText(Messages.EdgesTab_EdgeTypes);
        edgeButton.addSelectionListener(new ShowEdgeTypesMenu());
    }
    
    private class ShowEdgeTypesMenu implements SelectionListener
    {
        public void widgetSelected(SelectionEvent e)
        {
            Menu popupMenu = new Menu(edgeButton);
            
            //This loop creates the Menu items and adds them to the menu.The Menu items
            //are the types of edges present in the file
            for (Integer type : edgeTypes)
            {
                MenuItem menuItem = new MenuItem(popupMenu, SWT.CHECK);
                menuItem.setText(vpg.describeEdgeType(type));
                menuItem.addSelectionListener(new MenuItemSelectionListener(type));
                menuItem.setSelection(edgeTypesToShow.contains(type));
            }
            
            new MenuItem(popupMenu, SWT.SEPARATOR);
            
            MenuItem menuItem = new MenuItem(popupMenu, SWT.CHECK);
            menuItem.setText(Messages.EdgesTab_ShowAllEdges);
            menuItem.addSelectionListener(new SelectAllSelectionListener());
            popupMenu.setVisible(true);

            while (!popupMenu.isDisposed() && popupMenu.isVisible())
                if (!popupMenu.getDisplay().readAndDispatch())
                    popupMenu.getDisplay().sleep();
            popupMenu.dispose();
        }

        public void widgetDefaultSelected(SelectionEvent e)
        {
            widgetSelected(e);
        }
    }

    private class MenuItemSelectionListener implements SelectionListener
    {
        private int edgeType;
        
        public MenuItemSelectionListener(int type)
        {
            this.edgeType = type;     
        }

        public void widgetSelected(SelectionEvent e)
        {
          //If the menu item has already been selected and clicked on once again
          //de-select it
            if (edgeTypesToShow.contains(edgeType)){
                edgeTypesToShow.remove(edgeType);
                
            }
            else
                edgeTypesToShow.add(edgeType);
            
            styledText.redraw();
        }

        public void widgetDefaultSelected(SelectionEvent e)
        {
            widgetSelected(e);
        }
    }

    private class SelectAllSelectionListener implements SelectionListener{
        
        public SelectAllSelectionListener(){
            
        }

        /* (non-Javadoc)
         * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
         */
        public void widgetSelected(SelectionEvent e)
        {
            edgeTypesToShow.addAll(edgeTypes);   
            showEdges = collectSelectedEdges(styledText.getCaretOffset());
            styledText.redraw();
        }

        /* (non-Javadoc)
         * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
         */
        public void widgetDefaultSelected(SelectionEvent e)
        {
            widgetSelected(e);
            
        }
    }

    private Set<VPGEdge<?,?,?>> collectSelectedEdges(int caretOffset)
    {
       //if the care offset happens to be within the edge then add the edge to the edgesToShow list
        HashSet<VPGEdge<?,?,?>> edgesToShow = new HashSet<VPGEdge<?,?,?>>();
        for (VPGEdge<?,?,?> edge : edgesInFile)
        {
            if (edge.getSource().getOffset() <= caretOffset
                && edge.getSource().getEndOffset() >= caretOffset)
            {
                edgesToShow.add(edge);
            }
            else if (edge.getSink().getOffset() <= caretOffset
                && edge.getSink().getEndOffset() >= caretOffset)
            {
                edgesToShow.add(edge);
            }
        }
        return edgesToShow;
    }

    private void createComposite(TabFolder tabfolder)
    {
        GridLayout layout = new GridLayout();
        layout.numColumns = 3;
        composite = new Composite(tabfolder, SWT.NONE);
        composite.setLayout(layout);
        edges.setControl(composite);
    }

    private void createRadioButtons()
    {
        createShowAllButton();
        createShowSelectedButton();
    }

    private void createShowAllButton()
    {
        showAll = new Button(composite, SWT.RADIO);
        showAll.setText(Messages.EdgesTab_ShowAllEdges);
        showAll.setSelection(false);
        showAll.addSelectionListener(new RadioButtonSelectionListener());
    }

    private void createShowSelectedButton()
    {
        showSelected = new Button(composite, SWT.RADIO);
        showSelected.setText(Messages.EdgesTab_ShowSelectedEdges);
        showSelected.setSelection(true);
        showSelected.addSelectionListener(new RadioButtonSelectionListener());
    }

    private final class RadioButtonSelectionListener implements SelectionListener
    {
        public void widgetSelected(SelectionEvent e)
        {
            styledText.redraw();
        }

        public void widgetDefaultSelected(SelectionEvent e)
        {
            widgetSelected(e);
        }
    }

    private void createStyledText()
    {
        styledText = new StyledText(composite, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.READ_ONLY);

        GridData gridData = new GridData();
        gridData.horizontalAlignment = GridData.FILL;
        gridData.verticalAlignment = GridData.FILL;
        gridData.grabExcessVerticalSpace = true;
        gridData.grabExcessHorizontalSpace = true;
        gridData.horizontalSpan = 3;
        gridData.verticalSpan = 1;
        styledText.setLayoutData(gridData);

        styledText.setFont(JFaceResources.getTextFont());
        styledText.addPaintListener(new EdgePainter(styledText));
        styledText.addCaretListener(new ShowEdgeCaretListener());  
    }

    private final class ShowEdgeCaretListener implements CaretListener
    {
        
        public void caretMoved(CaretEvent event)
        {
            showEdges = collectSelectedEdges(event.caretOffset);
            displayCaretInformation(event);
            styledText.redraw();
        }

        
        private void displayCaretInformation(CaretEvent event)
        {
            int caretLine =  styledText.getLineAtOffset(styledText.getCaretOffset());
            int lineOffset = styledText.getOffsetAtLine(caretLine);
            int caretOffset = styledText.getCaretOffset();
            int caretColumn = caretOffset-lineOffset+1 ; 
           
            label.setText(
                Messages.bind(
                    Messages.EdgesTab_LineColOffset, new Object[] {
                        caretLine+1,
                        caretColumn,
                        styledText.getCaretOffset() }));
            label.pack();
        }
    }

    private final class EdgePainter implements PaintListener
    {
  
        private final StyledText styledText;       
        
        private EdgePainter(StyledText styledText)
        {
            this.styledText = styledText;     
        }
       

        public void paintControl(PaintEvent e)
        {
           //Depending  upon whether if edgesTypesToShow list contains an edge this loop draws a rectangle around
            //the edge and calls the constructor of the DrawEdgesAndArrows class to draw lines between the source and sink
            for (VPGEdge< ? , ? , ? > edge : edgesInFile)
            {
                if (edgeTypesToShow.contains(edge.getType()))
                {
                    Color defaultColor = e.gc.getForeground();
                   //depending upon the type of edge the color of the edges and lines is decided.
                    e.gc.setForeground(setColor(edge.getType()));
                    IVPGNode source = edge.getSource();
                    IVPGNode sink = edge.getSink();
                    
                    
                    if (source.getFilename().equals(filename) && sink.getFilename().equals(filename))
                    {
                        Rectangle srcRect = drawRectangle(e, source.getOffset(), source.getEndOffset());
                        Rectangle sinkRect = drawRectangle(e, sink.getOffset(), sink.getEndOffset());
    
                        if (srcRect != null && sinkRect != null)
                        {
                            if(showAll.getSelection()||showEdges.contains(edge)){
                                displayEdgesAndArrows(e.gc,sinkRect,srcRect);
                                
                            }
                            
                        }
                    }
                    else
                    {
                        // TODO: Handle this case later
                    }
                    e.gc.setForeground(defaultColor);
                }
            }
        }
  
        private void displayEdgesAndArrows(GC gc, Rectangle sinkRect, Rectangle srcRect)
        {
            new EdgeArrow(srcRect, sinkRect).drawOn(gc);
        }
        
        private Color setColor(int type)
        {
            return color.get(type%color.size());    
        }


        private Rectangle drawRectangle(PaintEvent e, int startOffset, int endOffset)
        {
            if (isValid(startOffset) && isValid(endOffset))
            {
                Rectangle srcRect = styledText.getTextBounds(startOffset, Math.max(0, endOffset-1));
                e.gc.drawRectangle(srcRect);
                return srcRect;
            }
            else
                return null;
        }

        private boolean isValid(int offset)
        {
            return offset >= 0 && offset < styledText.getCharCount();
        }
    }       

    @SuppressWarnings("unchecked")
    public void showEdges(String file_selected, EclipseVPG vpg)
    {
        this.filename = file_selected;
        Object ast = vpg.acquireTransientAST(filename);
        
        if (ast == null)
            styledText.setText(Messages.bind(Messages.EdgesTab_UnableToParse, filename));
        else
            styledText.setText(vpg.getSourceCodeFromAST(ast));
 
        edgesInFile = new ArrayList<VPGEdge< ? , ? , ? >>();
        
        for (VPGEdge< ? , ? , ? > edge : (Iterable<VPGEdge< ? , ? , ? >>)vpg.getAllEdgesFor(filename))
            edgesInFile.add(edge);
        
        edgeTypes = new HashSet<Integer>();
        
        for (VPGEdge<?,?,?> edge : (Iterable<VPGEdge<?,?,? >>)vpg.getAllEdgesFor(filename))
            edgeTypes.add(edge.getType());
        
        edgeButton.setEnabled(edgeTypes.size() != 0);
    }
}