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

import com.k_int.AdminApp.widgets.RelatedObjectPanel;
import com.k_int.AdminApp.gui.AdminControllerComponent;
import com.k_int.AdminApp.gui.SearchView.RecordSelectionController;
import com.k_int.AdminApp.gui.SearchView.RecordSelectionConsumer;
import com.k_int.AdminApp.gui.ControllerOwner;
import org.apache.commons.jxpath.JXPathContext;
import java.util.logging.*;

public class RelatedObjectComponentModel implements RecordModelListener, ControllerOwner, RecordSelectionConsumer
{
    private static Logger cat = Logger.getLogger("com.k_int.AdminApp.gui.RecordView.RelatedObjectComponentModel");
  private String access_path;
  private String display_value_access_path;
  private RelatedObjectPanel control;
  private Object record = null;
  private static final String EMPTY_STRING="";
  private AdminControllerComponent controller = null;
  private String descriptor;
  private String repository;
  private JXPathContext context = null;
  private boolean editable = true;

  private ActionListener change_action_listener = new ActionListener() {
    public void actionPerformed(ActionEvent e)
    {
      cat.finest("change related object action");
      selectAlternateRecord();
    }

    protected void finalize()
    {
      cat.finest("change_action_listener::finalize()");
    }
  };

  public RelatedObjectComponentModel(String access_path, 
                                     String display_value_access_path,
                                     RelatedObjectPanel control,
                                     String descriptor,
                                     String repository)
  {
    this.access_path = access_path;
    this.display_value_access_path = display_value_access_path;
    this.control = control;
    this.descriptor = descriptor;
    this.repository = repository;

    control.addChangeButtonActionListener(change_action_listener);
  }

  public void recordChanged(Object record, boolean editable)
  {
    this.record = record;
    this.editable = editable;

    context = JXPathContext.newContext(record);
    control.setEditable(editable);
    refresh();
  }
  

  public void refresh()
  {
    try
    {
      Object related_object = context.getValue(access_path);
                                                                                                                                        
      if ( related_object != null )
      {
        Object value = context.getValue(display_value_access_path);
                                                                                                                                        
        if ( value != null )
          control.setDisplayText(value.toString());
        else
          control.setDisplayText(EMPTY_STRING);
      }
      else
      {
        control.setDisplayText(EMPTY_STRING);
      }
    }
    catch ( org.apache.commons.jxpath.JXPathException e )
    {
        cat.log(Level.SEVERE,"REfres,eh exception");
     // e.printStackTrace();
      // log.log(Level.FINE,"No value available",e);
    }
  }

  public void setEditable(boolean is_editable)
  {
    cat.finest("setEditable "+is_editable+"does nothing");
    // control.setEditable(is_editable);
    // Nothing to do here.
  }

  public void synchronizeViewToModel()
  {
      cat.finest("Does nothing");
    // Nothing to do.. It's not possible to "edit" a related attribute.. Only
    // to change the related object via the change button on the UI which will
    // cause an update to the model. Which will cause a "RecordChanged" event.
  }

  protected void finalize()
  {
    cat.finest("RelatedObjectComponentModel::finalize()");
  }

  public void setController(AdminControllerComponent c)
  {
    this.controller = c;
  }

  private void selectAlternateRecord()
  {
    try
    {
      RecordSelectionController rpc = new RecordSelectionController(descriptor,
                                                                    repository,
                                                                    controller.getConfig(),
                                                                    "Search..",
                                                                    this, // This object gets notified of close
                                                                    controller.getRootController(),
                                                                    true,
                                                                    this);
                                                                                                                                        
      controller.getRootController().addComponent(rpc);
    }
    catch ( javax.naming.NamingException ne )
    {
        cat.log(Level.SEVERE,"Exception selecting alternate record",ne);
      //ne.printStackTrace();
    }
  }

  public void componentCloseNotification(AdminControllerComponent component)
  {
    cat.finest("Does nothing");
  }

  public void notify(Object[] selected_objects)
  {
    if ( ( selected_objects.length == 1 ) && ( context != null ) )
    {
      context.setValue(access_path,selected_objects[0]);
      refresh();
    }
    else
    {
      cat.log(Level.SEVERE,"Error.. too many records selected");
    }
  }
}
