/*
 * ReportDesignerPanel.java
 *
 * Created on August 28, 2007, 12:21 AM
 */

package com.jaspersoft.ireport.designer;

import com.jaspersoft.ireport.designer.dnd.DesignerDropTarget;
import com.jaspersoft.ireport.designer.ruler.RulerPanel;
import java.awt.BorderLayout;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JComponent;
import net.sf.jasperreports.engine.design.JasperDesign;

        
/**
 *
 * @author  gtoffoli
 */
public class ReportDesignerPanel extends javax.swing.JPanel {
 
    private List<JasperDesignObserver> observers = new ArrayList<JasperDesignObserver>();
    JasperDesign jasperDesign = null;
    
    private RulerPanel hRuler = null;

    public RulerPanel getHRuler() {
        return hRuler;
    }

    public RulerPanel getVRuler() {
        return vRuler;
    }
    private RulerPanel vRuler = null;
    
    public boolean isGridVisible() {
        return getScene().isGridVisible();
    }

    public void setGridVisible(boolean b) {
        getScene().setGridVisible(b);
    }
    
    public boolean isSnapToGrid() {
        return getScene().isSnapToGrid();
    }

    public void setSnapToGrid(boolean b) {
        getScene().setSnapToGrid(b);
    }

    /**
     * The jasperDesign is loaded in background, since it involves in some I/O operations.
     * To get the JasperDesign currenctly active invoke getJasperDesign. If it returns true,
     * register yourself as JasperDesignObserver to get the design as soon it is available.
     * The Observer return the JasperDesign. If you get null again, this is
     * because the JasperDesign loading is failed for some reason (like a wrong XML syntax).
     */
    public JasperDesign getJasperDesign() {
        return jasperDesign;
    }
    
    /**
     * Update the JasperDesign to edit and notify all the JasperDesignObserver(s) registered using
     * addJasperDesignObserver.
     * When an observer is notified, it is removed from the list of objects to notify.
     * See getJasperDesign for more details.
     */
    public void setJasperDesign(JasperDesign jasperDesign) {
        this.jasperDesign = jasperDesign;
        
        
        getScene().setJasperDesign(jasperDesign);
        if (jasperDesign == null) return;
                
        // notify all the observers...
        for (JasperDesignObserver jdo  : observers)
        {
            jdo.jasperDesignAvailable(this.jasperDesign);
        }
        observers.clear();
    
    }
    private ReportObjectScene scene = null;
    private JComponent myView = null;
    
    /** Creates new form ReportDesignerPanel */
    public ReportDesignerPanel() {
        initComponents();
        scene = new ReportObjectScene();
        myView = scene.getJComponent();
        
        jScrollPaneMainReport.setViewportView(myView);
        
        hRuler = new RulerPanel(this);
        myView.addMouseMotionListener(hRuler);
        hRuler.addGuideLineChangedListener(scene);
        jPanel1.add(hRuler, BorderLayout.CENTER);
    
        vRuler = new RulerPanel(this);
        vRuler.setVertical(true);
        myView.addMouseMotionListener(vRuler);
        vRuler.addGuideLineChangedListener(scene);
        jPanel2.add(vRuler, BorderLayout.CENTER);
        myView.setDropTarget(new DesignerDropTarget(scene));
    }

    static private double[] zoomSteps = new double[]{0.25, 0.5, 0.75, 1.0, 1.5, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0};
    public void zoomIn() {
        double zoom = this.getScene().getZoomFactor();
        
        for (int i=0; i<zoomSteps.length; ++i)
        {
            if (zoom < zoomSteps[i])
            {
                zoom = zoomSteps[i];
                break;
            }
        }
        
        this.getScene().setZoomFactor( zoom );
        this.getScene().validate();
    }
    
    public void zoomOut() {
        
        double zoom = this.getScene().getZoomFactor();
        
        for (int i=zoomSteps.length-1; i>=0; --i)
        {
            if (zoom > zoomSteps[i])
            {
                zoom = zoomSteps[i];
                break;
            }
        }
        
        this.getScene().setZoomFactor( zoom );
        this.getScene().validate();
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPaneMainReport = new javax.swing.JScrollPane();
        jPanel1 = new javax.swing.JPanel();
        jPanel2 = new javax.swing.JPanel();

        jScrollPaneMainReport.setBorder(null);

        jPanel1.setMinimumSize(new java.awt.Dimension(100, 20));
        jPanel1.setPreferredSize(new java.awt.Dimension(100, 20));
        jPanel1.setLayout(new java.awt.BorderLayout());

        jPanel2.setBackground(new java.awt.Color(255, 255, 204));
        jPanel2.setMinimumSize(new java.awt.Dimension(20, 0));
        jPanel2.setPreferredSize(new java.awt.Dimension(20, 0));
        jPanel2.setLayout(new java.awt.BorderLayout());

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                .add(jPanel2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .add(0, 0, 0)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 345, Short.MAX_VALUE)
                    .add(jScrollPaneMainReport, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 345, Short.MAX_VALUE))
                .add(0, 0, 0))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .add(0, 0, 0)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(jPanel2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 270, Short.MAX_VALUE)
                    .add(jScrollPaneMainReport, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 270, Short.MAX_VALUE))
                .add(0, 0, 0))
        );
    }// </editor-fold>//GEN-END:initComponents
    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JScrollPane jScrollPaneMainReport;
    // End of variables declaration//GEN-END:variables
    
    /**
     *  See getJasperDesign() for more details.
     * 
     */
    public void addJasperDesignObserver(JasperDesignObserver jdo)
    {
        observers.add(jdo);
    }

    /**
     *  See getJasperDesign() for more details.
     * 
     */
    public void removeJasperDesignObserver(JasperDesignObserver jdo)
    {
        observers.remove(jdo);
    }
    
    public interface JasperDesignObserver {
        public void jasperDesignAvailable(JasperDesign jd);
    }

    public ReportObjectScene getScene() {
        return scene;
    }

    public void setScene(ReportObjectScene scene) {
        this.scene = scene;
    }
    
    
}
