/**
 * Title:
 * @version:    $Id: EditRecordController.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.RecordView;

import java.awt.*;
import com.k_int.AdminApp.config.*;

import javax.swing.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import net.sf.hibernate.*;
import com.k_int.AdminApp.gui.ControllerOwner;
import com.k_int.AdminApp.gui.ExplorerView.AdminController;
import com.k_int.AdminApp.gui.AdminControllerComponent;
import com.k_int.AdminApp.gui.OneToMany;
import java.util.logging.*;


public class EditRecordController extends AbstractRecordController
{
    private static Logger cat = Logger.getLogger("com.k_int.AdminApp.gui.RecordView.EditRecordCOntroller");
    private boolean needs_hibernate_save;
    private boolean save_new_enabled;
    private JPanel view;
    private Object[] associated_objects;
    private JButton abandon_button;
    
  
  public EditRecordController(ConfigHolder config, 
                              Session session, 
                              String name,
                              boolean needs_hibernate_save, 
                              boolean save_new_enabled,
                              ControllerOwner owner,
                              AdminController top,
                              boolean is_closeable)
  {
    super(config, session, name, owner, top, is_closeable);
    this.needs_hibernate_save = needs_hibernate_save;
    this.save_new_enabled = save_new_enabled;
    this.view = createView();
    this.is_closeable = is_closeable;
  }
  
  
  
  
//added by rob to deal with the hibernate management of records which are the 'children'
// of a parent i.e. the 'many' part of a one to many 'parent'
//.......
 public EditRecordController(ConfigHolder config, 
                             Session session, 
                             String name,
                             boolean needs_hibernate_save, 
                             boolean save_new_enabled,
                             ControllerOwner owner,
                             AdminController top,
                             boolean is_closeable,
                             OneToMany parent)
 {
   super(config, session, name, owner, top, is_closeable);
   this.needs_hibernate_save = needs_hibernate_save;
   this.save_new_enabled = save_new_enabled;
   this.view = createView();
   this.is_closeable = is_closeable;
   this.parent=parent;
 }  
  
  
  
  
  
  
 // added by rob to deal with the hibernate management of a record
 // and associated objects
 //.......
  public EditRecordController(ConfigHolder config, 
							  Session session, 
							  String name,
							  boolean needs_hibernate_save, 
							  boolean save_new_enabled,
							  ControllerOwner owner,
							  AdminController top,
							  boolean is_closeable,
							  Object[] associated_objects)
  {
	super(config, session, name, owner, top, is_closeable);
	this.needs_hibernate_save = needs_hibernate_save;
	this.save_new_enabled = save_new_enabled;
	this.view = createView();
	this.is_closeable = is_closeable;
	this.associated_objects=associated_objects;
  }
  

  public EditRecordController(ConfigHolder config, 
                              String repository_id,
                              String name,
                              boolean needs_hibernate_save, 
                              boolean save_new_enabled,
                              ControllerOwner owner,
                              AdminController top,
                              boolean is_closeable) throws net.sf.hibernate.HibernateException
  {
    super(config, repository_id, name, owner, top, is_closeable);
    this.needs_hibernate_save = needs_hibernate_save;
    this.save_new_enabled = save_new_enabled;
    this.view = createView();
    this.is_closeable = is_closeable;
  }


  // public Component selectView(String view_id)
    public Component getView()
    {
        cat.fine("EditRecordController:: getView(), name is "+name);
        return view;
    }

  public JPanel createView()
  {
    JPanel result = new JPanel(new BorderLayout());
    JPanel button_panel = new JPanel(new FlowLayout());

    JButton save_continue_button = new JButton("Save and Continue");
    save_continue_button.addActionListener( 
      new ActionListener() { public void actionPerformed(ActionEvent e) { onSaveAndContinue(); } } );
    button_panel.add(save_continue_button);

    JButton save_close_button = new JButton("Save and Close");
    save_close_button.addActionListener(
      new ActionListener() { public void actionPerformed(ActionEvent e) { onSaveAndClose(); } } );
    button_panel.add(save_close_button);

    if ( save_new_enabled )
    {
      JButton save_new_button = new JButton("Save and New");
      save_new_button.addActionListener(
        new ActionListener() { public void actionPerformed(ActionEvent e) { onSaveAndNew(); } } );
      button_panel.add(save_new_button);
    }

    abandon_button = new JButton("Exit without Save");
    abandon_button.addActionListener(
      new ActionListener() { public void actionPerformed(ActionEvent e) { onAbandon(); } } );
    button_panel.add(abandon_button);

    result.add( button_panel, BorderLayout.NORTH);

    if ( record_panel != null )
    {
      result.add( record_panel, BorderLayout.CENTER);
    }
    
    return result;
  }

  public void onSaveAndContinue()
  {
    // Walk the list of text control models and pull their values back into the
    // object we are editing... Lists are something different...
    // Question is: do we want a more proactive "onChange" way of pushing
    // changes back to the base model?
    cat.fine("onSaveAndContinue()");
    doSave();
  }

  public void onSaveAndClose()
  {
    cat.fine("onSaveAndClose()");
    doSave();
    close();
  }

  public void onSaveAndNew()
  {
    cat.fine("onSaveAndNew()");
    doSave();
  }

  public void onAbandon()
  {
    // Should be easy
    cat.fine("onAbandon()");  
    cat.fine("source record is "+source_record);
    abandoned=true;
    close(); 
  }

  protected void finalize()
  {
  }

    private void doSave()
    {
        cat.fine("doSave()"+needs_hibernate_save+" "+source_record);
        if(controller_owner instanceof AbstractRecordController )
        {
            ((AbstractRecordController) controller_owner).synchronizeFormAndModel();
        }
        synchronizeFormAndModel();
	    abandon_button.setEnabled(false);
        try
        {

            if ( needs_hibernate_save )
            {
                cat.fine("Save record");
                if(associated_objects!=null) // added by Rob
                {                    
        	       for (int i=0;i<associated_objects.length;i++)
        	       {
        	           cat.fine("Saving associated object "+associated_objects[i]);
        		      session.save(associated_objects[i]);
        	       }
        	       associated_objects=null;
                }
                session.save(source_record);
                needs_hibernate_save = false;
            }
            else
            {
                cat.fine("Update record");
                session.update(source_record);
                
            }
            session.flush();
            session.connection().commit();
        }
        catch ( net.sf.hibernate.HibernateException he )
        {
            cat.log(Level.SEVERE,"Error",he);
            //he.printStackTrace();
        }
        catch ( java.sql.SQLException sqle )
        {
            cat.log(Level.SEVERE,"Error",sqle);
            //sqle.printStackTrace();
        }
    }


  public void selectTemplate(String view_id)
  {
    // If there is already a component present, remove it
    if ( record_panel != null )
      view.remove(record_panel);

    // Cause our superclass to load the identified view into its record_panel member
    super.selectTemplate(view_id);

    // Now modify the edit record panel layout to use that view instead of the current one.
    view.add(record_panel, BorderLayout.CENTER);
  }

  public Session getSession()
  {
    return session;
  }

    public void componentCloseNotification(AdminControllerComponent component)
    {
        cat.finest("Edit record controller componentCloseNotification "+source_record);
        cat.finest("Abandoned == "+abandoned);
        if(abandoned==false)
        {
            refresh();
            abandon_button.setEnabled(false);
        }
    }

}
