/*
 *    SCCS ID: %Z%%M% %I% %E% SST
 *
 *    Copyright (c) 1992-1993 Mark Soloway.  All rights reserved.
 *    See SST_LEGAL_NOTICE file for terms of the license.
 */

#include "FileChooser.h"
#include "CommandMenu.h"
#include "AlphanumericInput.h"
#include "ListChoice.h"
#include "Button.h"
#include "PopUpWindow.h"
#include "object_manager_ui.h"

#include "TTFile.h"
#include "TTObjectSpec.h"

#define ADD_PROPERTY_FLAG "add_property_flag"

static void display_objects (AlphanumericInput *);
static void display_properties (char *, UIObject *);
static void display_values (char *, char *, UIObject *);

#if (XV_VERSION_NUMBER >= 3200)
void file_button_handler (UIObject *object)
{
  FileChooser *file_chooser = (FileChooser *)
			      object->getObjectData (FILE_CHOOSER_ADDRESS);
  file_chooser->show (TRUE);
}

void file_chooser_handler (UIObject *object)
{
  FileChooser *fc = (FileChooser *)object;

  char *path = fc->getChosenPath ();
  if (path) {
    AlphanumericInput *file = (AlphanumericInput *)
			      object->getObjectData (OBJECT_FILE);
    file->setValue (path);
    display_objects (file);
  }
}
#endif

void create_object_handler (UIObject *object)
{
  PopUpWindow *create_object_popup =
   (PopUpWindow *) object->getObjectData (CREATE_OBJECT_POPUP);
  create_object_popup->setLeftFooter ((char *) NULL); 
  create_object_popup->show (TRUE);

  return;
}

void delete_object (UIObject *object)
{
  ListChoice *object_list = (ListChoice *) object->getObjectData (OBJECT_LIST);

  char *objid = object_list->getChoice (1, objid);
  if (objid) {
    int          mark = tt_mark (); 
    Tt_status    status;
    TTObjectSpec tt_object (objid, status);

    if (status < TT_WRN_LAST) {
      status = tt_object.destroy ();
      if (status < TT_WRN_LAST) {
	AlphanumericInput *file_object =
         (AlphanumericInput *) object->getObjectData (OBJECT_FILE);
        display_objects (file_object);
      }
    }

    AlphanumericInput *object_id_display = (AlphanumericInput *) 
					   object->getObjectData (OBJECT);
    char *displayed_objid = object_id_display->getValue (displayed_objid);
    if (displayed_objid && !strcmp (displayed_objid, objid)) {
      PopUpWindow *edit_object_properties =
	(PopUpWindow *) object->getObjectData (EDIT_OBJECT_PROPERTIES);
      edit_object_properties->setPinned (FALSE);
      edit_object_properties->show (FALSE);
    }

    if (displayed_objid) delete displayed_objid;

    object_id_display = (AlphanumericInput *)
	                object->getObjectData (PROPERTY_OBJECT);
    displayed_objid = object_id_display->getValue (displayed_objid);
    if (displayed_objid && !strcmp (displayed_objid, objid)) {
      PopUpWindow *property_values_popup =
	(PopUpWindow *) object->getObjectData (PROPERTY_VALUES_POPUP);
      property_values_popup->setPinned (FALSE);
      property_values_popup->show (FALSE);
    }

    tt_release (mark);
    if (displayed_objid) delete displayed_objid;
    delete objid;
  }
  
  return;
}

void edit_object_properties_handler (UIObject *object)
{
  ListChoice *object_list = (ListChoice *) object->getObjectData (OBJECT_LIST);
  char *objid = object_list->getChoice (1, objid);

  PopUpWindow *edit_object_properties =
    (PopUpWindow *) object->getObjectData (EDIT_OBJECT_PROPERTIES);
  display_properties (objid, edit_object_properties);

  edit_object_properties->setPinned (TRUE);
  edit_object_properties->show (TRUE);

  delete objid;
  return;
}

void add_property_handler (UIObject *object)
{
  Button *apply_change = (Button *)
                         object->getObjectData (ADD_PROPERTY_APPLY);
  apply_change->setObjectData (ADD_PROPERTY_FLAG, (Generic *) -1);

  PopUpWindow *change_property_popup =
    (PopUpWindow *) object->getObjectData (CHANGE_PROPERTY_POPUP);
  change_property_popup->setLabel ("Add Property");
  change_property_popup->setLeftFooter ((char *) NULL);
  change_property_popup->show (TRUE);

  return;
}

void set_property_handler (UIObject *object)
{
  Button *apply_change = (Button *)
                         object->getObjectData (ADD_PROPERTY_APPLY);
  apply_change->setObjectData (ADD_PROPERTY_FLAG, (Generic *) 0);

  PopUpWindow *change_property_popup =
    (PopUpWindow *) object->getObjectData (CHANGE_PROPERTY_POPUP);
  change_property_popup->setLabel ("Set Property");
  change_property_popup->setLeftFooter ((char *) NULL);
  change_property_popup->show (TRUE);

  return;
}

void delete_property_handler (UIObject *object)
{
  ListChoice *property_list =
    (ListChoice  *) object->getObjectData (OBJECT_PROPERTY_LIST);
  char *property_name = property_list->getChoice (1, property_name);

  if (property_name) {
    AlphanumericInput *object_id = (AlphanumericInput *)
                                   object->getObjectData (OBJECT);
    char *objid = object_id->getValue (objid); 
    if (objid) {
      int          mark = tt_mark ();
      Tt_status    status;
      TTObjectSpec tt_object (objid, status);
      if (status < TT_WRN_LAST) {
        status = tt_object.setProperty (property_name, (char *) NULL);
	if (status < TT_WRN_LAST) {
	  status = tt_object.write ();
          if (status < TT_WRN_LAST) {
	    (void)tt_object.getPropertyCount (property_name, status);
	    if (status != TT_OK) {
              property_list->deleteChoice (property_name);
	    }

	    AlphanumericInput *name_display =
	     (AlphanumericInput *) object->getObjectData (PROPERTY_NAME);
	    char *displayed_name = name_display->getValue (displayed_name);

	    if (!strcmp (property_name, displayed_name)) {
	      PopUpWindow *property_values_popup =
		(PopUpWindow *) object->getObjectData (PROPERTY_VALUES_POPUP);
	      display_values (objid, property_name, property_values_popup);
	    }
	  }
        }
      }

      tt_release (mark);
      delete objid;
    }

    delete property_name;
  }

  return;
}

void file_notify_handler (UIObject *object)
{
  display_objects ((AlphanumericInput *) object);
  return;
}

static void display_objects (AlphanumericInput *file)
{
  ListChoice *object_list = (ListChoice *) file->getObjectData (OBJECT_LIST);
  object_list->deleteAllChoices ();

  char *value = file->getValue (value);
  if (value) {
    int       mark = tt_mark ();
    Tt_status status;
    TTFile    tt_file (value, status);

    TTObjectSpecArray *array = tt_file.getObjectSpecs (status);
    if (array && (status < TT_WRN_LAST)) {
      char *objid;
      int   num_objects = array->getSize ();
      for (int i=0; i < num_objects; i++) {
	objid = ((*array) [i])->getID (status);
	if (objid && (status < TT_WRN_LAST)) {
	  object_list->addChoice (objid);
	}
      }
    }

    tt_release (mark);
    if (array) delete array;
    delete value;
  }

  return;
}

void object_list_handler (UIObject *object)
{
  InputEvent *event = object->getEvent ();
  char       *objid = object->getValue (objid);

  switch (((ListChoice *) object)->getOperation ()) {
  case DESELECT:
    break;

  case SELECT:
    if (event->isDoubleClick ()) {
      PopUpWindow *edit_object_properties =
	(PopUpWindow *) object->getObjectData (EDIT_OBJECT_PROPERTIES);
      display_properties (objid, edit_object_properties);

      edit_object_properties->setPinned (TRUE);
      edit_object_properties->show (TRUE);
    }
    break;

  case VALIDATE:
    break;

  case DELETE:
    break;

  case UNKNOWN:
  default:
    break;
  }

  delete objid;
  return;
}

void values_button_notify_handler (UIObject *object)
{
  AlphanumericInput *selected_object =
    (AlphanumericInput *) object->getObjectData (OBJECT);           
  char *objid = selected_object->getValue (objid);
 
  ListChoice *property_list =
    (ListChoice *) object->getObjectData (OBJECT_PROPERTY_LIST);
  char *name = property_list->getChoice (1, name);

  PopUpWindow *property_values_popup =
    (PopUpWindow *) object->getObjectData (PROPERTY_VALUES_POPUP);  
  display_values (objid, name, property_values_popup);

  property_values_popup->setPinned (TRUE);
  property_values_popup->show (TRUE);

  if (objid) delete objid;
  if (name) delete name;
  return;
}

void property_list_handler (UIObject *object)
{
  InputEvent *event = object->getEvent ();
  char       *name = object->getValue (name);
  char       *objid;

  switch (((ListChoice *) object)->getOperation ()) {
  case DESELECT:
    break;

  case SELECT:
    if (event->isDoubleClick ()) {
      AlphanumericInput *selected_object =
	(AlphanumericInput *) object->getObjectData (OBJECT);
      objid = selected_object->getValue (objid);

      PopUpWindow *property_values_popup =
	(PopUpWindow *) object->getObjectData (PROPERTY_VALUES_POPUP);
      display_values (objid, name, property_values_popup);

      property_values_popup->setPinned (TRUE);
      property_values_popup->show (TRUE);

      if (objid) delete objid;
    }

    break;

  case VALIDATE:
    break;

  case DELETE:
    break;

  case UNKNOWN:
  default:
    break;
  }

  delete name;
  return;
}

void add_property (UIObject *object)
{
  int add_property = (int) object->getObjectData (ADD_PROPERTY_FLAG);

  AlphanumericInput *property_name =
    (AlphanumericInput *) object->getObjectData (ADD_PROPERTY_NAME);
  char *name = property_name->getValue (name);

  AlphanumericInput *property_value =
    (AlphanumericInput *) object->getObjectData (ADD_PROPERTY_VALUE);
  char *value = property_value->getValue (value);

  PopUpWindow *change_property_popup =
    (PopUpWindow *) object->getObjectData (CHANGE_PROPERTY_POPUP);

  if (name && strlen (name)) {
    AlphanumericInput *object_id = (AlphanumericInput *)
                                   object->getObjectData (OBJECT);
    int   new_property;
    char *objid = object_id->getValue (objid);

    if (objid) {
      int          mark = tt_mark ();
      Tt_status    status;
      TTObjectSpec tt_object (objid, status);

      if (add_property) {
        status = tt_object.addProperty (name, value);
	new_property = (tt_object.getPropertyCount (name, status) == 1);
      }
      else {
	new_property = (tt_object.getPropertyCount (name, status) == 0);
        status = tt_object.setProperty (name, value);
      }

      if (status < TT_WRN_LAST) {
	status = tt_object.write ();
      }

      if (status < TT_WRN_LAST) {
        if (new_property) {
	  ListChoice *property_list =
	    (ListChoice *) object->getObjectData (OBJECT_PROPERTY_LIST);
          property_list->addChoice (name);
        }
	else {
          change_property_popup->setLeftFooter ("Property operation successful");

	  AlphanumericInput *name_display =
	    (AlphanumericInput *) object->getObjectData (PROPERTY_NAME);
	  char *displayed_name = name_display->getValue (displayed_name);

	  if (!strcmp (displayed_name, name)) {
	    PopUpWindow *property_values_popup =
	      (PopUpWindow *) object->getObjectData (PROPERTY_VALUES_POPUP);
	    display_values (objid,
			    name,
			    property_values_popup);
          }
        }
      }

      tt_release (mark);
      delete objid;
    }
    else {
      change_property_popup->setLeftFooter ("No object ID specified");
    }
  }
  else {
    change_property_popup->setLeftFooter ("No property name specified");
  }

  if (name) delete name;
  if (value) delete value;
  return;
}

void add_property_cancel_notify_handler (UIObject *object)
{
  PopUpWindow *change_property_popup =
    (PopUpWindow *) object->getObjectData (CHANGE_PROPERTY_POPUP);
  change_property_popup->setPinned (FALSE);
  change_property_popup->show (FALSE);

  return;
}

void create_object_cancel_handler (UIObject *object)
{
  PopUpWindow *create_object_popup =
    (PopUpWindow *) object->getObjectData (CREATE_OBJECT_POPUP);
  create_object_popup->setPinned (FALSE);
  create_object_popup->show (FALSE);

  return;
}

void create_object (UIObject *object)
{
  PopUpWindow *create_object_popup =
    (PopUpWindow *) object->getObjectData (CREATE_OBJECT_POPUP);
  AlphanumericInput *file_object =
    (AlphanumericInput *) object->getObjectData (OBJECT_FILE);
  AlphanumericInput *type_object =
    (AlphanumericInput *) object->getObjectData (OBJECT_TYPE);

  char *file = file_object->getValue (file);
  char *type = type_object->getValue (type);

  if (file && type && strlen (file) && strlen (type)) {
    int          mark = tt_mark ();
    Tt_status    status;
    TTObjectSpec tt_object (file, type, status);
    if (status == TT_OK) {
      status = tt_object.write ();
    }

    if (status == TT_OK) {
      create_object_popup->setLeftFooter ("Object create successful");
      display_objects (file_object);
    }
    else {
      create_object_popup->setLeftFooter ("Object create failed");
    }

    tt_release (mark);
  }
  else if ((!file && !type) ||  (!strlen (file) && !strlen (type))) {
    create_object_popup->setLeftFooter ("No object file or type specified");
  }
  else if (!file || !strlen (file)) {
    create_object_popup->setLeftFooter ("No object file specified");
  }
  else {
    create_object_popup->setLeftFooter ("No object type specified");
  }

  if (file) delete file;
  if (type) delete type;
  return;
}

static void display_properties (char     *objid,
				UIObject *object)
{
  AlphanumericInput *object_id = (AlphanumericInput *)
                                 object->getObjectData (OBJECT);
  AlphanumericInput *object_type = (AlphanumericInput *)
                                   object->getObjectData (OBJECT_TYPE);
  ListChoice *property_list = (ListChoice *)
                              object->getObjectData (OBJECT_PROPERTY_LIST);

  if (objid) {
    int          mark = tt_mark (); 
    Tt_status    status;
    TTObjectSpec object (objid, status);
    if (status < TT_WRN_LAST) {
      object_id->setValue (objid);

      char *type = object.getOType (status);
      if (status < TT_WRN_LAST) { 
	object_type->setValue (type);
	property_list->deleteAllChoices ();

        char *property;
        int   num_properties = object.getPropertyNameCount (status);
        for (int i=0; (status < TT_WRN_LAST) && (i < num_properties); i++) {
          property = object.getPropertyName (i, status);
          if (property && (status < TT_WRN_LAST)) {
	    property_list->addChoice (property);
	  }
        }
      }
    }

    tt_release (mark);
  }
}

static void display_values (char     *objid,
			    char     *property_name,
			    UIObject *object)
{
  AlphanumericInput *object_id_display =
    (AlphanumericInput *) object->getObjectData (PROPERTY_OBJECT);        
  AlphanumericInput *property_name_display =
    (AlphanumericInput *) object->getObjectData (PROPERTY_NAME);      
  ListChoice *property_values =
    (ListChoice *) object->getObjectData (PROPERTY_VALUES);                

  if (objid) {
    int          mark = tt_mark (); 
    Tt_status    status;
    TTObjectSpec object (objid, status);
    if (status < TT_WRN_LAST) {
      object_id_display->setValue (objid);
      property_values->deleteAllChoices ();

      if (property_name) {
        property_name_display->setValue (property_name);
 
        char          *property_value;
        unsigned char *property_bvalue;
        int            length;
        int num_values = object.getPropertyCount (property_name, status);
        for (int i=0; (status < TT_WRN_LAST) && (i < num_values); i++) {
          status = object.getProperty (property_name, i, property_value);
          status = object.getProperty (property_name,
				       i,
				       property_bvalue,
				       length);
          if (property_value && (status < TT_WRN_LAST)) {
	    if (strlen (property_value) == length) {
              property_values->addChoice (property_value);
	    }
	    else {
	      property_values->addChoice ("<Non-ASCII Bytes>");
	    }
	  }
	  else {
	    property_values->addChoice ("<NULL>");
	  }
        }
      }  
    }  

    tt_release (mark);
  } 
}
