package de.javasoft.synthetica.democenter.examples.jyscrollpanemap;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JViewport;
import javax.swing.ScrollPaneConstants;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import de.javasoft.plaf.synthetica.SyntheticaLookAndFeel;
import de.javasoft.swing.JYScrollPaneMap;

/**
 * Demonstrates the ScrollPaneMap together with a zoomable panel component.  
 */
@SuppressWarnings("serial")
public class ZoomableScrollPaneMap extends JFrame
{
  private ZoomablePanel zoomablePanel;

  /**
   * Static main method for application startup. 
   */
  public static void main(String[] args)
  {
    EventQueue.invokeLater(new Runnable()
    {
      public void run()
      {
        try
        {
          UIManager.setLookAndFeel("de.javasoft.plaf.synthetica.SyntheticaStandardLookAndFeel");
          new ZoomableScrollPaneMap();
        }
        catch (Exception e)
        {
          e.printStackTrace();
        }
      }
    });
  }
  
  public ZoomableScrollPaneMap()
  {
    super("Zoomable JYScrollPaneMap Demo");

    JScrollPane scroller = new JScrollPane();
//@highlight
    scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
    scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    JYScrollPaneMap map = new JYScrollPaneMap(scroller);
    map.setToolTipText("Keep the mouse button pressed to display the map.");
    scroller.setCorner(JScrollPane.LOWER_TRAILING_CORNER, map);
//@/highlight
    zoomablePanel = new ZoomablePanel(300); 
    scroller.setViewportView(zoomablePanel);
    add(scroller);
    add(createSliderPanel(), BorderLayout.NORTH);    
    
    //setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);      
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    setSize(800, 600);
    setLocationRelativeTo(null);        //center
    setVisible(true);
  }

  private JComponent createSliderPanel()
  {
    JComponent p = new JPanel(new BorderLayout());
    int zoom = zoomablePanel.getZoom();
    final JLabel label = new JLabel("<html>Zoom %<br>" + zoom + "%");
    p.add(label, BorderLayout.LINE_START);
    JSlider slider = new JSlider(100, 4000, zoom);
    slider.setSnapToTicks(true);
    slider.setMinorTickSpacing(100);
    slider.setMajorTickSpacing(400);
    slider.setLabelTable(slider.createStandardLabels(400, 100));
    slider.setPaintLabels(true);
    slider.setPaintTicks(true);
    slider.addChangeListener(new ChangeListener()
    {      
      public void stateChanged(ChangeEvent evt)
      {
        JSlider slider = (JSlider)evt.getSource();
        label.setText("<html>Zoom %<br>" + slider.getValue() + "%");
        zoomablePanel.setZoom(slider.getValue());
        ((JViewport)zoomablePanel.getParent()).revalidate();
      }
    });
    p.add(slider);
    return p;    
  }  
  
  /**
   * Zoomable Panel
   */
  private static class ZoomablePanel extends JPanel
  {
    //zoom level in percent
    private int zoom = 100;
    private int width = 1600;
    private int height = 600;
    
    public ZoomablePanel(int zoom)
    {
      setLayout(new BorderLayout());
      setZoom(zoom);
    };
    
    private void setZoom(int zoom)
    {
      this.zoom = zoom;
      int zoomedWidth = (int)(width*zoom/100f);
      int zoomedHeight = (int)(height*zoom/100f);
      setPreferredSize(new Dimension(zoomedWidth, zoomedHeight));
    }
    
    private int getZoom()
    {
      return zoom;
    }
    
    @Override
    protected void paintComponent(Graphics g)
    {
//@highlight
      float ratio = SyntheticaLookAndFeel.getClientProperty("Synthetica.previewImageRatio", this, 1f);
      float scaleFactor = ratio*zoom/100f;
//@/highlight

      Graphics2D g2 = (Graphics2D) g;
      g2.setPaint(new GradientPaint(0, 0, new Color(0x40FF40), getWidth(), getHeight(), new Color(0xFF4040)));
      g2.fillRect(0, 0, getWidth(), getHeight());
      
      float x = 100*scaleFactor;
      float y = getHeight()/2 - 200*scaleFactor;
      float w = getWidth() - 200*scaleFactor;
      float h = 400*scaleFactor;
      g2.setPaint(new GradientPaint(x, y, new Color(0x40FFFF), w, h, new Color(0xFFFF40)));
      g2.fill(new Ellipse2D.Float(x, y, w, h));
    }    
  }
  
}
