
/*
 ****************************************************************************** *
 *
 *   Copyright (C) 1999-2003, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 ****************************************************************************** *
 *   file name:  gnomelayout.cpp
 *
 *   created on: 09/04/2001
 *   created by: Eric R. Mader
 */

#include <gnome.h>
#include "freetype/freetype.h"

#include "unicode/ustring.h"
#include "unicode/uscript.h"

#include "GnomeFontInstance.h"

#include "paragraph.h"

#include "GnomeGUISupport.h"
#include "GnomeFontMap.h"
#include "UnicodeReader.h"
#include "ScriptCompositeFontInstance.h"

#define ARRAY_LENGTH(array) (sizeof array / sizeof array[0])

struct Context
{
    long width;
    long height;
    Paragraph *paragraph;
};

static TT_Engine engine;
static GnomeGUISupport *guiSupport;
static GnomeFontMap *fontMap;
static ScriptCompositeFontInstance *font;

static GSList *appList = NULL;

GtkWidget *newSample(const gchar *fileName);
void       closeSample(GtkWidget *sample);

void showabout(GtkWidget *widget, gpointer data)
{
    GtkWidget *aboutBox;
    const gchar *writtenBy[] = {
        "Eric Mader",
        NULL
    };

    aboutBox = gnome_about_new("Gnome Layout Sample",
                               "0.1",
                               "Copyright (C) 1998-2002 By International Business Machines Corporation and others. All Rights Reserved.",
                               writtenBy,
                               "A simple demo of the ICU LayoutEngine.",
                               NULL);

    gtk_widget_show(aboutBox);
}

void notimpl(GtkObject *object, gpointer data)
{
    gnome_ok_dialog("Not implemented...");
}

gchar *prettyTitle(const gchar *path)
{
  gchar *name  = g_basename(path);
  gchar *title = g_strconcat("Gnome Layout Sample - ", name, NULL);

  return title;
}

void openOK(GtkObject *object, gpointer data)
{
  GtkFileSelection *fileselection = GTK_FILE_SELECTION(data);
  GtkWidget *app = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(fileselection), "app"));
  Context *context = (Context *) gtk_object_get_data(GTK_OBJECT(app), "context");
  gchar *fileName  = g_strdup(gtk_file_selection_get_filename(fileselection));
  Paragraph *newPara;

  gtk_widget_destroy(GTK_WIDGET(fileselection));

  newPara = Paragraph::paragraphFactory(fileName, font, guiSupport);

  if (newPara != NULL) {
    gchar *title = prettyTitle(fileName);
    GtkWidget *area = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(app), "area"));

    if (context->paragraph != NULL) {
      delete context->paragraph;
    }

    context->paragraph = newPara;
    gtk_window_set_title(GTK_WINDOW(app), title);

    gtk_widget_hide(area);
    context->paragraph->breakLines(context->width, context->height);
    gtk_widget_show_all(area);

    g_free(title);
  }

  g_free(fileName);
}

void openfile(GtkObject *object, gpointer data)
{
  GtkWidget *app = GTK_WIDGET(data);
  GtkWidget *fileselection;
  GtkWidget *okButton;
  GtkWidget *cancelButton;

  fileselection =
    gtk_file_selection_new("Open File");

  gtk_object_set_data(GTK_OBJECT(fileselection), "app", app);

  okButton =
    GTK_FILE_SELECTION(fileselection)->ok_button;

  cancelButton =
    GTK_FILE_SELECTION(fileselection)->cancel_button;

  gtk_signal_connect(GTK_OBJECT(fileselection), "destroy",
		     GTK_SIGNAL_FUNC(gtk_main_quit), NULL);

  gtk_signal_connect(GTK_OBJECT(okButton), "clicked",
		     GTK_SIGNAL_FUNC(openOK), fileselection);

  gtk_signal_connect_object(GTK_OBJECT(cancelButton), "clicked",
		     GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(fileselection));

  gtk_window_set_modal(GTK_WINDOW(fileselection), TRUE);
  gtk_widget_show(fileselection);
  gtk_main();
}

void newapp(GtkObject *object, gpointer data)
{
  GtkWidget *app = newSample("Sample.txt");

  gtk_widget_show_all(app);
}

void closeapp(GtkWidget *widget, gpointer data)
{
  GtkWidget *app = GTK_WIDGET(data);

  closeSample(app);
}

void shutdown(GtkObject *object, gpointer data)
{
    gtk_main_quit();
}

GnomeUIInfo fileMenu[] =
{
  GNOMEUIINFO_MENU_NEW_ITEM("_New Sample",
			    "Create a new Gnome Layout Sample",
			    newapp, NULL),

  GNOMEUIINFO_MENU_OPEN_ITEM(openfile, NULL),
  GNOMEUIINFO_SEPARATOR,
  GNOMEUIINFO_MENU_CLOSE_ITEM(closeapp, NULL),
  GNOMEUIINFO_MENU_EXIT_ITEM(shutdown, NULL),
  GNOMEUIINFO_END
};

GnomeUIInfo helpMenu[] =
{
    // GNOMEUIINFO_HELP("gnomelayout"),
    GNOMEUIINFO_MENU_ABOUT_ITEM(showabout, NULL),
    GNOMEUIINFO_END
};

GnomeUIInfo mainMenu[] =
{
    GNOMEUIINFO_SUBTREE(N_("File"), fileMenu),
    GNOMEUIINFO_SUBTREE(N_("Help"), helpMenu),
    GNOMEUIINFO_END
};

gint eventDelete(GtkWidget *widget, GdkEvent *event, gpointer data)
{
  closeSample(widget);

  // indicate that closeapp  already destroyed the window 
  return TRUE;
}

gint eventConfigure(GtkWidget *widget, GdkEventConfigure *event, Context *context)
{
  if (context->paragraph != NULL) {
    context->width  = event->width;
    context->height = event->height;

    if (context->width > 0 && context->height > 0) {
        context->paragraph->breakLines(context->width, context->height);
    }
  }

  return TRUE;
}

gint eventExpose(GtkWidget *widget, GdkEvent *event, Context *context)
{
  if (context->paragraph != NULL) {
    gint maxLines = context->paragraph->getLineCount() - 1;
    gint firstLine = 0, lastLine = context->height / context->paragraph->getLineHeight();
    GnomeSurface surface(widget);

    context->paragraph->draw(&surface, firstLine, (maxLines < lastLine)? maxLines : lastLine);
  }

  return TRUE;
}

GtkWidget *newSample(const gchar *fileName)
{
  gchar     *title   = NULL;
  GtkWidget *app     = NULL;
  GtkWidget *area    = NULL;
  Context   *context = new Context();

  context->width  = 600;
  context->height = 400;
  context->paragraph = Paragraph::paragraphFactory(fileName, font, guiSupport);

  if (context->paragraph != NULL) {
    GtkStyle *style;
    gchar *title = prettyTitle(fileName);

    app = gnome_app_new("gnomeLayout", title);

    gtk_object_set_data(GTK_OBJECT(app), "context", context);

    gtk_window_set_default_size(GTK_WINDOW(app), 600 - 24, 400);

    gnome_app_create_menus_with_data(GNOME_APP(app), mainMenu, app);

    gtk_signal_connect(GTK_OBJECT(app), "delete_event",
		       GTK_SIGNAL_FUNC(eventDelete), NULL);

    area = gtk_drawing_area_new();
    gtk_object_set_data(GTK_OBJECT(app), "area", area);

#if 1
    style = gtk_style_copy(gtk_widget_get_style(area));

    for (int i = 0; i < 5; i += 1) {
      style->fg[i] = style->white;
    }
    
    gtk_widget_set_style(area, style);
#endif

    gnome_app_set_contents(GNOME_APP(app), area);

    gtk_signal_connect(GTK_OBJECT(area),
                       "expose_event",
                       GTK_SIGNAL_FUNC(eventExpose),
                       context);

    gtk_signal_connect(GTK_OBJECT(area),
                       "configure_event",
                       GTK_SIGNAL_FUNC(eventConfigure),
                       context);

    appList = g_slist_prepend(appList, app);
  }

  g_free(title);

  return app;
}

void closeSample(GtkWidget *app)
{
  Context *context = (Context *) gtk_object_get_data(GTK_OBJECT(app), "context");

  if (context->paragraph != NULL) {
    delete context->paragraph;
  }

  delete context;

  appList = g_slist_remove(appList, app);

  gtk_widget_destroy(app);

  if (appList == NULL) {
    gtk_main_quit();
  }
}

int main (int argc, char *argv[])
{
    LEErrorCode   fontStatus = LE_NO_ERROR;
    GtkWidget     *app;

    TT_Init_FreeType(&engine);

    gnome_init("gnomelayout", "0.1", argc, argv);

    guiSupport = new GnomeGUISupport();
    fontMap    = new GnomeFontMap(engine, "FontMap.Gnome", 24, guiSupport, fontStatus);
    font       = new ScriptCompositeFontInstance(fontMap);

    if (LE_FAILURE(fontStatus)) {
        TT_Done_FreeType(engine);
        return 1;
    }

    if (argc <= 1) {
      app = newSample("Sample.txt");
      gtk_widget_show_all(app);
    } else {
      for (int i = 1; i < argc; i += 1) {
	app = newSample(argv[i]);
	gtk_widget_show_all(app);
      }
    }

    gtk_main();

    delete font;
    delete guiSupport;

    TT_Done_FreeType(engine);

    exit(0);
}
