/*
 * Copyright (C) 2005 - 2007 JasperSoft Corporation.  All rights reserved. 
 * http://www.jaspersoft.com.
 *
 * Unless you have purchased a commercial license agreement from JasperSoft,
 * the following license terms apply:
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 *
 * This program is distributed WITHOUT ANY WARRANTY; and without 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 this program; if not, see http://www.gnu.org/licenses/gpl.txt
 * or write to:
 *
 * Free Software Foundation, Inc.,
 * 59 Temple Place - Suite 330,
 * Boston, MA  USA  02111-1307
 *
 *
 *
 *
 * BandsDialog.java
 * 
 * Created on 10 maggio 2003, 9.51
 *
 */

package it.businesslogic.ireport.gui;

import it.businesslogic.ireport.gui.event.ReportBandChangedEvent;
import it.businesslogic.ireport.gui.event.ReportBandsSelectionEvent;
import it.businesslogic.ireport.gui.event.ReportElementChangedEvent;
import it.businesslogic.ireport.gui.event.ReportElementsSelectionEvent;
import it.businesslogic.ireport.gui.event.ReportListener;
import javax.swing.table.*;
import javax.swing.*;
import javax.swing.event.*;
import it.businesslogic.ireport.*;
import it.businesslogic.ireport.util.*;

import java.util.*;
/**
 *
 * @author  Administrator
 */
public class BandsDialog extends javax.swing.JDialog implements ReportListener {
    
    
    private JReportFrame jReportFrame=null;
    
    private Band selectedBand = null;
    
    /** Creates new form BandsDialog */
    public BandsDialog(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
        applyI18n();
        this.pack();
         Misc.centerFrame(this);
         jListBands.setModel(new DefaultListModel());      
        /* 
         
         this.jRTextExpressionArea.getDocument().addDocumentListener( new javax.swing.event.DocumentListener() {
            public void changedUpdate(javax.swing.event.DocumentEvent evt)
            {
                jRTextExpressionAreaTextChanged();
            }
            public void insertUpdate(javax.swing.event.DocumentEvent evt) {
                jRTextExpressionAreaTextChanged();
            }
            public void removeUpdate(javax.swing.event.DocumentEvent evt) {
                jRTextExpressionAreaTextChanged();
            }
        });
         *
         */ 
         
         
        javax.swing.KeyStroke escape =  javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ESCAPE, 0, false);
        javax.swing.Action escapeAction = new javax.swing.AbstractAction() {
            public void actionPerformed(java.awt.event.ActionEvent e) {
                setVisible(false);
            }
        };
       
        getRootPane().getInputMap(javax.swing.JComponent.WHEN_IN_FOCUSED_WINDOW).put(escape, "ESCAPE");
        getRootPane().getActionMap().put("ESCAPE", escapeAction);


        //to make the default button ...
        this.getRootPane().setDefaultButton(this.jButton1);
        
        MainFrame.getMainInstance().addReportListener(this);
         
    }
    
    
    private void jRTextExpressionAreaTextChanged()
    {
            
    }
    
    public void jTableBandsListSelectionValueChanged(javax.swing.event.ListSelectionEvent e)
    {
       
    }
    
     public void updateBands() {
    
         Object selected = getSelectedBand();
         boolean isSelected = false;

        ((DefaultListModel)jListBands.getModel()).removeAllElements();
    
        if (jReportFrame == null) return;
        Enumeration e = jReportFrame.getReport().getBands().elements();
        while (e.hasMoreElements())
        {
            it.businesslogic.ireport.Band band = (it.businesslogic.ireport.Band)e.nextElement();
            ((DefaultListModel)jListBands.getModel()).addElement(band);    
            if (selected == band)
            {
                jListBands.setSelectedValue(selected, true);
                isSelected = true;
            }
        }    
        
        if (!isSelected && jReportFrame.getReport().getBands().size() > 0)
        {
            jListBands.setSelectedIndex(0);
        }
    }
    /** 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() {
        java.awt.GridBagConstraints gridBagConstraints;

        jPanelFields = new javax.swing.JPanel();
        jPanelButtons = new javax.swing.JPanel();
        jPanel2 = new javax.swing.JPanel();
        jPanel3 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jNumberFieldHeight = new it.businesslogic.ireport.gui.JNumberField();
        jCheckBoxSplitAllowed = new javax.swing.JCheckBox();
        jRTextExpressionArea = new it.businesslogic.ireport.gui.JRTextExpressionArea();
        jButton1 = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        jListBands = new javax.swing.JList();

        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                closeDialog(evt);
            }
        });

        jPanelFields.setLayout(new java.awt.BorderLayout(4, 4));

        jPanelButtons.setLayout(new java.awt.BorderLayout());

        jPanelButtons.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Band properties"));
        jPanelButtons.setMinimumSize(new java.awt.Dimension(100, 10));
        jPanelButtons.setPreferredSize(new java.awt.Dimension(300, 250));
        jPanel2.setLayout(new java.awt.BorderLayout());

        jPanel3.setLayout(new java.awt.GridBagLayout());

        jPanel3.setPreferredSize(new java.awt.Dimension(10, 55));
        jLabel1.setText("Print When Expression");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(3, 3, 0, 3);
        jPanel3.add(jLabel1, gridBagConstraints);

        jLabel2.setText("Band height");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(3, 3, 0, 3);
        jPanel3.add(jLabel2, gridBagConstraints);

        jNumberFieldHeight.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        jNumberFieldHeight.setText("0");
        try {
            jNumberFieldHeight.setDecimals(0);
        } catch (java.beans.PropertyVetoException e1) {
            e1.printStackTrace();
        }
        jNumberFieldHeight.setMinimumSize(new java.awt.Dimension(80, 19));
        jNumberFieldHeight.setPreferredSize(new java.awt.Dimension(80, 19));
        jNumberFieldHeight.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jNumberFieldHeightActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(0, 3, 3, 3);
        jPanel3.add(jNumberFieldHeight, gridBagConstraints);

        jCheckBoxSplitAllowed.setSelected(true);
        jCheckBoxSplitAllowed.setText("Split allowed");
        jCheckBoxSplitAllowed.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBoxSplitAllowedActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridheight = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(3, 3, 3, 3);
        jPanel3.add(jCheckBoxSplitAllowed, gridBagConstraints);

        jRTextExpressionArea.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        jRTextExpressionArea.setElectricScroll(0);
        jRTextExpressionArea.setMinimumSize(new java.awt.Dimension(0, 0));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(3, 3, 3, 3);
        jPanel3.add(jRTextExpressionArea, gridBagConstraints);

        jButton1.setText("Apply");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
        jPanel3.add(jButton1, gridBagConstraints);

        jPanel2.add(jPanel3, java.awt.BorderLayout.CENTER);

        jPanelButtons.add(jPanel2, java.awt.BorderLayout.CENTER);

        jPanelFields.add(jPanelButtons, java.awt.BorderLayout.CENTER);

        getContentPane().add(jPanelFields, java.awt.BorderLayout.CENTER);

        jScrollPane1.setToolTipText("");
        jScrollPane1.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        jScrollPane1.setPreferredSize(new java.awt.Dimension(150, 300));
        jListBands.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        jListBands.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        jListBands.setToolTipText("List of bands");
        jListBands.setMaximumSize(new java.awt.Dimension(32767, 32767));
        jListBands.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                jListBandsValueChanged(evt);
            }
        });

        jScrollPane1.setViewportView(jListBands);

        getContentPane().add(jScrollPane1, java.awt.BorderLayout.WEST);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed

        boolean changed = false;
        
        
        Band b = getSelectedBand();
        if (b == null) return;
        int okHeight = b.getHeight();
        
        int newHeight = updateBandHeight(getJReportFrame().getReport(), b, (int)jNumberFieldHeight.getValue());
        
        if (newHeight >= 0 && okHeight != newHeight)
        {
            try {
                    jNumberFieldHeight.setValue(newHeight);
            } catch (Exception ex){}
            
            getJReportFrame().setIsDocDirty(true);
            getJReportFrame().updateScrollBars();
            getJReportFrame().getReportPanel().repaint();
            
            changed = true;
        }
        
        // Setting the new jCheckBoxSplitAllowed...
         b = getSelectedBand();
         if (b != null)
         {
             b.setSplitAllowed( jCheckBoxSplitAllowed.isSelected());
             changed = true;
         }
         
         if (!b.getPrintWhenExpression().equals(jRTextExpressionArea.getText() ))
        {
            getSelectedBand().setPrintWhenExpression( jRTextExpressionArea.getText() );
            changed = true;
        }
         
        if (changed )
        {
             getJReportFrame().fireReportListenerReportBandChanged(new ReportBandChangedEvent(getJReportFrame(),getSelectedBand(), ReportBandChangedEvent.CHANGED));
        }
        
    }//GEN-LAST:event_jButton1ActionPerformed

    private void jCheckBoxSplitAllowedActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBoxSplitAllowedActionPerformed
        
       
        
    }//GEN-LAST:event_jCheckBoxSplitAllowedActionPerformed

    private void jNumberFieldHeightActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jNumberFieldHeightActionPerformed
        
        
        
                                        
    }//GEN-LAST:event_jNumberFieldHeightActionPerformed

    private void jListBandsValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_jListBandsValueChanged
        //
        
        updateSelection();
    }//GEN-LAST:event_jListBandsValueChanged
    
    public void updateSelection()
    {
        // This solve a bug with the not reached focus event...
        jNumberFieldHeightActionPerformed(null);
        
        
        if (jListBands.getModel().getSize() == 0)
        {
             try {
                this.jNumberFieldHeight.setValue( 0 );
            } catch (Exception ex) {}
            this.jRTextExpressionArea.setText("");
             jCheckBoxSplitAllowed.setSelected(false);
            return;
        }
        
        if (jListBands.getSelectedIndex() < 0) 
        {
            jListBands.setSelectedIndex(0);
            return;
        }
        
        selectedBand = (Band)jListBands.getSelectedValue();
        try {
            this.jNumberFieldHeight.setValue( selectedBand.getHeight());
        } catch (Exception ex) {}
        this.jRTextExpressionArea.setText( selectedBand.getPrintWhenExpression());
        this.jCheckBoxSplitAllowed.setSelected(  selectedBand.isSplitAllowed() );
    }
    
    
    /** Closes the dialog */
    private void closeDialog(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_closeDialog
        setVisible(false);
        dispose();
    }//GEN-LAST:event_closeDialog
    
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        new BandsDialog(new javax.swing.JFrame(), true).setVisible(true);
    }
    
    /** Getter for property jReportFrame.
     * @return Value of property jReportFrame.
     *
     */
    public it.businesslogic.ireport.gui.JReportFrame getJReportFrame() {
        return jReportFrame;
    }    
    
    /** Setter for property jReportFrame.
     * @param jReportFrame New value of property jReportFrame.
     *
     */
    public void setJReportFrame(it.businesslogic.ireport.gui.JReportFrame jReportFrame) {
        this.jReportFrame = jReportFrame;
        
        // Update all...
        if (jReportFrame == null) 
        {
            setVisible(false);
            return;
        }
        
        this.setTitle(jReportFrame.getReport().getName()+" "+I18n.getString("bandsDialog.bands"," bands..."));
        if (isVisible())
        {
            updateBands();
        }
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JCheckBox jCheckBoxSplitAllowed;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JList jListBands;
    private it.businesslogic.ireport.gui.JNumberField jNumberFieldHeight;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanelButtons;
    private javax.swing.JPanel jPanelFields;
    private it.businesslogic.ireport.gui.JRTextExpressionArea jRTextExpressionArea;
    private javax.swing.JScrollPane jScrollPane1;
    // End of variables declaration//GEN-END:variables
    
    public void setVisible(boolean visible)
    {
        if (visible == isVisible()) return;
        super.setVisible(visible);
        if (visible == true) 
        {
            this.setJReportFrame(jReportFrame);
        }
    }
    
    public void setSelectedBand(String bandName )
    {
        for (int i=0; i<jListBands.getModel().getSize(); ++i)
        {
            Band b = (Band)jListBands.getModel().getElementAt( i );
            if (b.getName().equals(bandName))
            {
                jListBands.setSelectedIndex( i );
                return;
            }
        }
    }

    public Band getSelectedBand() {
        return selectedBand;
    }

    public void setSelectedBand(Band selectedBand) {
        this.selectedBand = selectedBand;
    }
    public void applyI18n(){
                // Start autogenerated code ----------------------
                jCheckBoxSplitAllowed.setText(I18n.getString("bandsDialog.checkBoxSplitAllowed","Split allowed"));
                // End autogenerated code ----------------------
                // Start autogenerated code ----------------------
                jButton1.setText(I18n.getString("bandsDialog.button1","Apply"));
                jLabel1.setText(I18n.getString("bandsDialog.label1","Print When Expression"));
                jLabel2.setText(I18n.getString("bandsDialog.label2","Band height"));
                // End autogenerated code ----------------------
                
                ((javax.swing.border.TitledBorder)jPanelButtons.getBorder()).setTitle( I18n.getString("bandsDialog.panelBorder.BandProperties","Band properties") );
    
                jListBands.setToolTipText(I18n.getString("bandsDialog.listBands","List of bands"));
    
    }
    
    
    /**
     * Return the new height or -1 if an exception occurred
     */
    public static int updateBandHeight(Report report, Band b, int newHeight)
    {
        if (b == null || report == null) return -1;
        int okHeight = b.getHeight();
        boolean changed = false;
        
	// 1. we set band height, but first we adjust elements position
	int delta = newHeight - b.getHeight();
	if (delta != 0)
	{
                changed = true;
                // Available space...
                int available_height = report.getHeight() - report.getTopMargin()- report.getBottomMargin();
                
                if (!b.getName().equals("background") &&
                    !( b.getName().equals("title") && report.isIsTitleNewPage()) &&
                    !( b.getName().equals("summary") &&report.isIsSummaryNewPage()))
                {
                    for (int i=0; i<report.getBands().size(); ++i)
                    {
                        Band aBand = (Band)report.getBands().elementAt(i);

                        if (!(aBand.getName().equals("background")) &&
                            !(aBand.getName().equals("title") && report.isIsTitleNewPage()) &&
                            !(aBand.getName().equals("summary") && report.isIsSummaryNewPage()) &&
                            !(aBand == b))
                        {
                            available_height -= aBand.getHeight();
                        }
                    }
                }
                
                okHeight = Math.max(0, Math.min(available_height, newHeight));
                				
                delta = okHeight - b.getHeight();
		// Redraw all under the min height...
                int band_h = report.getBandYLocation(b);
		b.setHeight( b.getHeight() + delta );
		int edge_y =  Math.min(report.getBandYLocation(b)+b.getHeight(),report.getBandYLocation(b)+b.getHeight()-delta);
		Enumeration e = report.getElements().elements();
		while (e.hasMoreElements())
		{
			ReportElement re = (ReportElement)e.nextElement();
			if (re.position.y >= edge_y+10)	
			{
				// I should add the distance form the base of resized band, and my element... 
                		int space_before_band = band_h - re.position.y - re.height;
				if (band_h <= report.getBandYLocation(re.getBand()) +10)
				space_before_band = 0;
				re.setPosition(new java.awt.Point(re.getPosition().x, re.getPosition().y+delta));	
                        }	
		}
                
                if (report.getReportFrame() != null)
                {
                    report.getReportFrame().setIsDocDirty(true);
                    report.getReportFrame().updateScrollBars();
                    report.getReportFrame().getReportPanel().repaint();
                }
        }
        
        return okHeight;
        
    }

    public void reportElementsSelectionChanged(ReportElementsSelectionEvent evt) {
    }

    public void reportElementsChanged(ReportElementChangedEvent evt) {
        
    }

    public void reportBandChanged(ReportBandChangedEvent evt) {
        updateSelection();
    }

    public void reportBandsSelectionChanged(ReportBandsSelectionEvent evt) {
    }
}
