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

package com.k_int.AdminApp.gui;

import java.awt.event.ActionEvent;
import java.lang.reflect.Method;
import com.k_int.AdminApp.config.ConfigHolder;
import com.k_int.AdminApp.gui.RecordView.EditRecordController;
import com.k_int.AdminApp.gui.RecordView.AbstractRecordController;
import org.apache.commons.jxpath.JXPathContext;

import java.util.logging.*;

/**
 *  This action can be used when editing an object which provides a factory method to create
 *  child records (For example, to create entries for a collection attribute). The action will
 *  use reflection to attempt to identify the named factory method on the target object,
 *  call it's create method, and then, if required, create an edit window for that new object
 *  using the default layout for the given class.
 */
public class GenericCreateChildAction extends AbstractRecordAction
{
    private static Logger cat = Logger.getLogger("com.k_int.AdminApp.gui.GenericCreateChildAction");
  private EditRecordController controller = null;
  private String factory_object_access_path = null;
  private String factory_method_name = null;
  private String action_name = null;
  

  public GenericCreateChildAction(EditRecordController controller,
                                  String factory_object_access_path,
                                  String factory_method_name,
                                  String action_name)
  {
    super();

    cat.fine("New GenericCreateChildAction()");

    this.controller = controller;
    this.factory_object_access_path = factory_object_access_path;
    this.factory_method_name = factory_method_name;
    this.action_name = action_name;

    setName(action_name);
    setShortDescription(action_name);
  }

  public void actionPerformed(ActionEvent evt)
  {
    cat.finest("Copout realisation of actionPerfomed for GenericCreateChildAction");
    ConfigHolder config = controller.getConfig();
    Object root_record = controller.getSourceRecord();
    Object factory_object = root_record;
   
    if ( factory_object_access_path != null )
      factory_object = JXPathContext.newContext(root_record).getValue(factory_object_access_path);

    // Now look for an appropriately named method
    Class factory_object_class = factory_object.getClass();
    cat.fine("FactoryObject is "+factory_object);
    try
    {
      Method m = factory_object_class.getMethod(factory_method_name,null);

      Object result = m.invoke(factory_object,null);
 
      if ( result != null )
      {
        // Spawn an edit record controller and associated bits :)
        String class_name = result.getClass().getName();
        String required_layout = config.lookupDefaultView(class_name);
        cat.finest("Required Layout is "+required_layout);
        EditRecordController rpc = null;
        
        if(factory_object instanceof OneToMany)
        {
            cat.fine("Instance of one to many");
            rpc = new EditRecordController(config,
                                                  ((AbstractRecordController)controller).getSession(),
                                                  //"Editing...",
                                                  action_name,
                                                  true,  // Needs save
                                                  false, // Allow save new
                                                  controller,
                                                  controller.getRootController(),
                                                  false,
                                                  (OneToMany)factory_object);            
        }
        else
        {
        rpc = new EditRecordController(config,
                                       ((AbstractRecordController)controller).getSession(),
                                       //"Editing...",
                                       action_name,
                                       true,  // Needs save
                                       false, // Allow save new
                                       controller,
                                       controller.getRootController(),
                                       false);
        }
        rpc.selectTemplate(required_layout);
        controller.getRootController().addComponent(rpc);
        rpc.recordChanged(result, true); 
      }
    }
    catch ( java.lang.NoSuchMethodException nsme )
    {
      nsme.printStackTrace();
    }
    catch ( java.lang.IllegalAccessException iae )
    {
      iae.printStackTrace();
    }
    catch ( java.lang.reflect.InvocationTargetException ite )
    {
      ite.printStackTrace();
    }
    finally
    {
    }
  }
}
