/**
 * Title:
 * @version:    $Id: SearchPanel.java,v 1.1 2004/11/15 13:47:50 rob Exp $
 * Copyright:   Copyright (C) 2003 Ian Ibbotson
 * @author:     Ian Ibbotson
 * Company:
 * Description:
 */

package com.k_int.AdminApp.gui.SearchView;

import java.awt.Component;
import java.awt.Container;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.BorderLayout;

import javax.swing.event.ListSelectionListener;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.JSplitPane;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.JComboBox;
import javax.swing.SwingConstants;

import com.k_int.QueryDescriptor.*;
import com.k_int.AdminApp.models.Search.*;
import com.k_int.AdminApp.gui.ExplorerView.Closeable;

import java.util.logging.*;
import java.util.Iterator;

public class SearchPanel extends JPanel implements Closeable, ActionListener
{
  private SearchModel sm = null;

  private static Logger cat = Logger.getLogger(SearchPanel.class.getName());

  private JSplitPane search_record_split;
  private JSplitPane query_results_split;
  private JPanel results_panel;
  private JPanel record_panel;
  private JPanel query_panel;
  private JTable results_table;
  private DBSearchTableModel table_model;
  private BaseSearchController controller;
  private int selected_row = -1;

  private ActionListener select_rows_action = new ActionListener() {
    public void actionPerformed(ActionEvent e)
    {
      cat.finest("Select rows button pressed");
      if ( ( controller != null ) && ( controller instanceof RecordSelectionController ) && ( selected_row != -1 ) )
      {
        ((RecordSelectionController)controller).notifySelection(new int[] { selected_row } );
      }
    }
  };

  public SearchPanel(BaseSearchController controller)
  {
    super();
    this.sm = controller.getModel();
    this.controller = controller;

    setup();
  }

  public boolean canClose()
  {
    return true;
  }

  public void close()
  {
    cat.finest("Close search panel");
    controller.close();
  }

  private void setup()
  {
    setLayout(new BorderLayout());
    // Structure is:
    //   Split panel, left=search, right=record
    //   search panel, split top=quert, bottom=results
    query_panel = new JPanel(new GridBagLayout());
    results_panel = new JPanel(new BorderLayout());
    table_model = new DBSearchTableModel(sm,"Default");
    DefaultTableColumnModel scm = new DefaultTableColumnModel();
    results_table = new JTable ( table_model, scm );
    JScrollPane jsp = new JScrollPane(results_table);
    results_table.createDefaultColumnsFromModel();
    results_table.setShowGrid( false );
    results_panel.add(jsp,BorderLayout.CENTER);
    record_panel = new JPanel();
    drawQuery(sm.getQueryDescriptor().getQuery(), query_panel);
    GridBagConstraints c = new GridBagConstraints();
    c.gridwidth = GridBagConstraints.REMAINDER;
    c.fill = GridBagConstraints.BOTH;
    c.weightx = 0.0;
    // c.weightx = 1.0;
    JButton search_button = new JButton("Search");
    search_button.addActionListener(this);
    query_panel.add(search_button,c);

    query_results_split = new JSplitPane(JSplitPane.VERTICAL_SPLIT, query_panel, results_panel);
    search_record_split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, query_results_split, record_panel);
    this.add(search_record_split,BorderLayout.CENTER);

    JPanel record_selection_panel = new JPanel();

    if ( controller.showRecordSelectionPanel() )
    {
      cat.finest("Showing record sel panel");
      JButton select_button = new JButton("Select");
      select_button.addActionListener(select_rows_action);
      JButton new_button = new JButton("Create New");
      record_selection_panel.add(select_button);
      record_selection_panel.add(new_button);
    }

    results_panel.add(record_selection_panel,BorderLayout.SOUTH);

    // Set up the list selection model for the results table
    ListSelectionModel row_selection_model = results_table.getSelectionModel();
    row_selection_model.addListSelectionListener(new ListSelectionListener() {
    public void valueChanged(ListSelectionEvent e) {
        //Ignore extra messages.
        if (e.getValueIsAdjusting()) return;
        
        ListSelectionModel lsm = (ListSelectionModel)e.getSource();
        if (lsm.isSelectionEmpty()) {
            //no rows are selected
            selected_row = -1;
        } else {
            selected_row = lsm.getMinSelectionIndex();
            cat.finest("Row selection change : "+selected_row);
            // showResultRowDetailRecord(selected_row);
            controller.notifyRowSelected(selected_row);
            //selectedRow is selected
        }
    } });

    results_table.addMouseListener( new MouseAdapter() {
      public void mouseClicked(MouseEvent e) {
        if ( e.getClickCount() == 2 ) {
          controller.notifyDoubleClickRow(selected_row);
        }
      }   
    } );
  }

  private void drawQuery(QueryNode qn, Container p)
  {
    // JPanel result = new JPanel(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();
    c.fill = GridBagConstraints.BOTH;
    c.weightx = 0.0;

    if ( qn instanceof BooleanNode )
    {
      BooleanNode bn = (BooleanNode)qn;

      // Add a dropcombo top left (west)
      String[] ops = { "And", "Or", "Not" };

      // result.add(new JComboBox(ops), BorderLayout.WEST);
      // result.add(rhs, BorderLayout.CENTER);
      c.gridwidth = 1; // Size 1 cell in grid
      c.weightx = 0.0;
      p.add(new JComboBox(ops),c);

      JPanel child_contents = new JPanel(new GridBagLayout());

      for ( Iterator i = bn.getComponents().iterator(); i.hasNext(); )
      {
        QueryNode child_node = (QueryNode) i.next();
        drawQuery(child_node,child_contents);
      }

      c.gridwidth = GridBagConstraints.REMAINDER;  // Should cause a new row in the gridbag
      c.weightx = 1.0;
      p.add(child_contents,c);
    }
    else if ( qn instanceof ExpressionNode )
    {
      ExpressionNode en = (ExpressionNode)qn;

      c.gridwidth = 1; // Size 1 cell in grid
      c.weightx = 0.0;
      JLabel label = new JLabel(en.getName()+" : ");
      label.setHorizontalAlignment(SwingConstants.RIGHT);
      label.setVerticalAlignment(SwingConstants.TOP);
      p.add(label,c);
      c.gridwidth = GridBagConstraints.REMAINDER;  // Should cause a new row in the gridbag
      c.weightx = 1.0;
      JTextField txt_field = new JTextField();
      txt_field.getDocument().addDocumentListener(new SearchFieldChangeDocumentListener(txt_field,sm,en.getName()));
      p.add(txt_field,c);
    }
    else
    {
      throw new RuntimeException("Unhandled query node");
    }
  }

  public void actionPerformed(ActionEvent e)
  {
    String a = e.getActionCommand();
    cat.finest("Action: "+a);
    if ( a.equals("Search") )
    {
      sm.evaluate();
      table_model.fireTableDataChanged();
      if ( sm.getRowCount() > 0 )
        results_table.setRowSelectionInterval( 0, 0 ); 
 
      // ((DefaultListSelectionModel)(results_table.getSelectionModel())).fireValueChanged(0,0,true);
      // results_table.tableChanged(new TableModelEvent(table_model));
    }
  }

  public void setLeftComponent(Component c)
  {
    search_record_split.setLeftComponent(c);
  }

  public void setRightComponent(Component c)
  {
    cat.finest("SearchPanel:: setRightComponent "+c);
    search_record_split.setRightComponent(c);
  }

  public void notifyChange()
  {
    cat.finest("SearchPanel::notifyChange....");
    //table_model.fireTableDataChanged();
  }

  // Need to add a select records action to this class that can be invoked via
  // keyboard shortcut or select records button.
}
