/*
 * Copyright (c) 2005-2015 KOM – Multimedia Communications Lab
 *
 * This file is part of PeerfactSim.KOM.
 * 
 * PeerfactSim.KOM is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 * 
 * PeerfactSim.KOM is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with PeerfactSim.KOM.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

package de.tud.kom.p2psim.impl.topology.movement.modularosm.attraction;


import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.util.LinkedList;

import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import de.tud.kom.p2psim.api.common.SimHost;
import de.tud.kom.p2psim.impl.topology.util.PositionVector;
import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView;
import de.tud.kom.p2psim.impl.topology.views.VisualizationTopologyView.VisualizationInjector;
import de.tud.kom.p2psim.impl.topology.views.visualization.ui.VisualizationComponent;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.IAttractionPoint;

public class AttractionPointViz extends JComponent
		implements VisualizationComponent {

	protected boolean showAttractionPoints = true;
	
	private JMenu menu;

	private final static int ATTR_SIZE = 5;

	private static Color COLOR_ATTR_POINT = Color.decode("#4A7B9D");

	public static LinkedList<LinkedList<SimHost>> clusters = new LinkedList<LinkedList<SimHost>>();
	public static LinkedList<Color> colors = new LinkedList<Color>();
	
	public LinkedList<IAttractionPoint> aps;
	
	public AttractionPointViz() {
        init();
	}
	
	public void setAttractionPoints(LinkedList<IAttractionPoint> aps) {
		this.aps = aps;
	}

	protected void init() {
        setBounds(0, 0, VisualizationInjector.getWorldX(),
                VisualizationInjector.getWorldY());
        setOpaque(true);
        setVisible(true);

        menu = new JMenu("Attraction Points");
        menu.add(createCheckboxAp());      
    }
	
	private JCheckBoxMenuItem createCheckboxAp() {
		final JCheckBoxMenuItem checkBox = new JCheckBoxMenuItem(
				"show attraction points", showAttractionPoints);
		checkBox.addChangeListener(new ChangeListener() {
			@Override
			public void stateChanged(ChangeEvent e) {
				showAttractionPoints = checkBox.isSelected();
				VisualizationInjector.invalidate();
			}
		});
		return checkBox;
	}

	
	@Override
	public void paint(Graphics g) {
		super.paintComponent(g);
		Graphics2D g2 = (Graphics2D) g;
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);

		if (showAttractionPoints) {
			drawAttractionPoints(g2);
		}
		
		if(true) {
			drawClusters(g2);
		}
	}

    /**
     * Provides access super.paintComponent() for extending classes.
     * @param g the Graphics object for painting.
     */
    protected void paintSuper(Graphics g)
    {
        super.paintComponent(g);
    }
    
    protected void drawClusters(Graphics2D g2)
    {
		// Composite gc = g2.getComposite();
		if(colors.isEmpty()) {
			for( int i = 0; i < 20; i++) {
				colors.add(new Color(new java.util.Random().nextInt()));
			}
		}
    	
		for (LinkedList<SimHost> group : clusters) {
			
			g2.setColor(colors.get(clusters.indexOf(group)));

			for (SimHost member : group) {
				PositionVector p = member.getTopologyComponent().getRealPosition();

				g2.fillOval(VisualizationInjector.scaleValue(p.getX()) - 10,
						VisualizationInjector.scaleValue(p.getY()) - 10, 20, 20);
			}

		}
    }

    /**
     * Draws the attraction points. This method has been extracted from paint()
     * to make it possible for extending class to override only this bit while leaving everything
     * else untouched.
     * @param g2 the Graphics2D object for painting.
     */
	protected void drawAttractionPoints(Graphics2D g2)
    {
		if(aps == null || aps.size() == 0) {
			return;
		}
		
		Composite gc = g2.getComposite();
		
        for (IAttractionPoint aPoint : aps) {
            Point point = ((PositionVector) aPoint).asPoint();
            // draw border
            g2.setColor(Color.BLACK);
            g2.setFont(VisualizationTopologyView.FONT_MEDIUM);
            g2.drawString(aPoint.getName(),
                    VisualizationInjector.scaleValue(point.x) - g2.getFontMetrics().stringWidth(aPoint.getName()) / 2,
                    VisualizationInjector.scaleValue(point.y - aPoint.getRadius() - 5) - ATTR_SIZE);
//            g2.setColor(COLOR_ATTR_POINT);
//            float alpha = 0.25f + (float) (aPoint.getWeight() / 2);
//            g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
//            g2.fillOval(
//                    VisualizationInjector.scaleValue(point.x) - ATTR_PAD,
//                    VisualizationInjector.scaleValue(point.y) - ATTR_PAD,
//                    ATTR_PAD * 2 + 1, ATTR_PAD * 2 + 1);
            g2.setColor(COLOR_ATTR_POINT);
            int radius = VisualizationInjector.scaleValue(aPoint.getRadius()) + ATTR_SIZE;
            g2.drawOval(VisualizationInjector.scaleValue(point.x) - radius,
                    VisualizationInjector.scaleValue(point.y) - radius,
                    radius * 2 + 1, radius * 2 + 1);
            
            g2.setComposite(gc);
        }
    }

    	@Override
	public String getDisplayName() {
		return "Attraction Points";
	}

	@Override
	public JComponent getComponent() {
		return this;
	}

	@Override
	public JMenu getCustomMenu() {
		return menu;
	}

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