/* 
 * Copyright (C) 2006, Jan Arne Petersen <jpetersen@jpetersen.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include <gtk/gtk.h>

struct label_params {
  char *description;			/* 0 */
  char *test;				/* 1 */
  int xpad;				/* 2 */
  int ypad;				/* 3 */
  double xalign;			/* 4 */
  double yalign;			/* 5 */
  PangoEllipsizeMode ellipsize;		/* 6 */
  GtkJustification justify;		/* 7 */
  gboolean line_wrap;			/* 8 */
  PangoWrapMode line_wrap_mode;		/* 9 */
  gboolean single_line_mode;		/* 10 */
  int width_chars;			/* 11 */
  int max_width_chars;			/* 12 */
};

#define NO PANGO_ELLIPSIZE_NONE
#define ST PANGO_ELLIPSIZE_START
#define MI PANGO_ELLIPSIZE_MIDDLE
#define EN PANGO_ELLIPSIZE_END

#define JL GTK_JUSTIFY_LEFT
#define JC GTK_JUSTIFY_CENTER
#define JR GTK_JUSTIFY_RIGHT
#define JF GTK_JUSTIFY_FILL

#define WO PANGO_WRAP_WORD
#define CH PANGO_WRAP_CHAR
#define WC PANGO_WRAP_WORD_CHAR

#define SHORTL "LEFT JUSTIFIED This is a short text\n\330\247\331\204\330\263\331\204\330\247\331\205 \330\271\331\204\331\212\331\203\331\205 \330\247\331\204\330\263\331\204\330\247\331\205 \330\271\331\204\331\212\331\203\331\205"

#define LONGL "LEFT JUSTIFIED This is really truly verily some very long text\n\330\247\331\204\330\263\331\204\330\247\331\205 \330\271\331\204\331\212\331\203\331\205 \330\247\331\204\330\263\331\204\330\247\331\205 \330\271\331\204\331\212\331\203\331\205 \330\247\331\204\330\263\331\204\330\247\331\205 \330\271\331\204\331\212\331\203\331\205"

#define LONGC "CENTERED This is really truly verily some very long text\n\330\247\331\204\330\263\331\204\330\247\331\205 \330\271\331\204\331\212\331\203\331\205 \330\247\331\204\330\263\331\204\330\247\331\205 \330\271\331\204\331\212\331\203\331\205 \330\247\331\204\330\263\331\204\330\247\331\205 \330\271\331\204\331\212\331\203\331\205"

#define LONGR "RIGHT JUSTIFIED This is really truly verily some very long text\n\330\247\331\204\330\263\331\204\330\247\331\205 \330\271\331\204\331\212\331\203\331\205 \330\247\331\204\330\263\331\204\330\247\331\205 \330\271\331\204\331\212\331\203\331\205 \330\247\331\204\330\263\331\204\330\247\331\205 \330\271\331\204\331\212\331\203\331\205"


/* DO NOT CHANGE THE ROWS!  They are numbered so that we can refer to
 * problematic rows in bug reports.  If you need a different test, just add a
 * new row at the bottom.  Also, please add your new row numbers to this column -------------------------------+
 * to keep things tidy.                                                                                        v
 */
static const struct label_params label_params[] = {
  /* Test alignment */

  { "0  0  0  0  NO JL F CH F -1 -1", SHORTL,  0,  0, 0.0, 0.0, NO, JL, FALSE, CH, FALSE, -1, -1 }, /* 1 */
  { "0  0  .5 0  NO JC F CH F -1 -1", SHORTL,  0,  0, 0.5, 0.0, NO, JL, FALSE, CH, FALSE, -1, -1 }, /* 2 */
  { "0  0  1  0  NO JR F CH F -1 -1", SHORTL,  0,  0, 1.0, 0.0, NO, JL, FALSE, CH, FALSE, -1, -1 }, /* 3 */
  { "0  0  0  .5 NO JL F CH F -1 -1", SHORTL,  0,  0, 0.0, 0.5, NO, JL, FALSE, CH, FALSE, -1, -1 }, /* 4 */
  { "0  0  .5 .5 NO JC F CH F -1 -1", SHORTL,  0,  0, 0.5, 0.5, NO, JL, FALSE, CH, FALSE, -1, -1 }, /* 5 */
  { "0  0  1  .5 NO JR F CH F -1 -1", SHORTL,  0,  0, 1.0, 0.5, NO, JL, FALSE, CH, FALSE, -1, -1 }, /* 6 */
  { "0  0  0  1  NO JL F CH F -1 -1", SHORTL,  0,  0, 0.0, 1.0, NO, JL, FALSE, CH, FALSE, -1, -1 }, /* 7 */
  { "0  0  .5 1  NO JC F CH F -1 -1", SHORTL,  0,  0, 0.5, 1.0, NO, JL, FALSE, CH, FALSE, -1, -1 }, /* 8 */
  { "0  0  1  1  NO JR F CH F -1 -1", SHORTL,  0,  0, 1.0, 1.0, NO, JL, FALSE, CH, FALSE, -1, -1 }, /* 9 */

  /* Test padding */

  { "10 10 0  0  NO JL F CH F -1 -1", SHORTL, 10, 10, 0.0, 0.0, NO, JL, FALSE, CH, FALSE, -1, -1 }, /* 10 */
  { "10 10 .5 0  NO JC F CH F -1 -1", SHORTL, 10, 10, 0.5, 0.0, NO, JL, FALSE, CH, FALSE, -1, -1 }, /* 11 */
  { "10 10 1  0  NO JR F CH F -1 -1", SHORTL, 10, 10, 1.0, 0.0, NO, JL, FALSE, CH, FALSE, -1, -1 }, /* 12 */
  { "10 10 0  .5 NO JL F CH F -1 -1", SHORTL, 10, 10, 0.0, 0.5, NO, JL, FALSE, CH, FALSE, -1, -1 }, /* 13 */
  { "10 10 .5 .5 NO JC F CH F -1 -1", SHORTL, 10, 10, 0.5, 0.5, NO, JL, FALSE, CH, FALSE, -1, -1 }, /* 14 */
  { "10 10 1  .5 NO JR F CH F -1 -1", SHORTL, 10, 10, 1.0, 0.5, NO, JL, FALSE, CH, FALSE, -1, -1 }, /* 15 */
  { "10 10 0  1  NO JL F CH F -1 -1", SHORTL, 10, 10, 0.0, 1.0, NO, JL, FALSE, CH, FALSE, -1, -1 }, /* 16 */
  { "10 10 .5 1  NO JC F CH F -1 -1", SHORTL, 10, 10, 0.5, 1.0, NO, JL, FALSE, CH, FALSE, -1, -1 }, /* 17 */
  { "10 10 1  1  NO JR F CH F -1 -1", SHORTL, 10, 10, 1.0, 1.0, NO, JL, FALSE, CH, FALSE, -1, -1 }, /* 18 */

  /* Test alignment */

  { "0  0  0  0  MI JL F CH F -1 -1", LONGL,  0,  0, 0.0, 0.0, MI, JL, FALSE, CH, FALSE, -1, -1 }, /* 19 */
  { "0  0  .5 0  MI JC F CH F -1 -1", LONGL,  0,  0, 0.5, 0.0, MI, JL, FALSE, CH, FALSE, -1, -1 }, /* 20 */
  { "0  0  1  0  MI JR F CH F -1 -1", LONGL,  0,  0, 1.0, 0.0, MI, JL, FALSE, CH, FALSE, -1, -1 }, /* 21 */
  { "0  0  0  .5 MI JL F CH F -1 -1", LONGL,  0,  0, 0.0, 0.5, MI, JL, FALSE, CH, FALSE, -1, -1 }, /* 22 */
  { "0  0  .5 .5 MI JC F CH F -1 -1", LONGL,  0,  0, 0.5, 0.5, MI, JL, FALSE, CH, FALSE, -1, -1 }, /* 23 */
  { "0  0  1  .5 MI JR F CH F -1 -1", LONGL,  0,  0, 1.0, 0.5, MI, JL, FALSE, CH, FALSE, -1, -1 }, /* 24 */
  { "0  0  0  1  MI JL F CH F -1 -1", LONGL,  0,  0, 0.0, 1.0, MI, JL, FALSE, CH, FALSE, -1, -1 }, /* 25 */
  { "0  0  .5 1  MI JC F CH F -1 -1", LONGL,  0,  0, 0.5, 1.0, MI, JL, FALSE, CH, FALSE, -1, -1 }, /* 26 */
  { "0  0  1  1  MI JR F CH F -1 -1", LONGL,  0,  0, 1.0, 1.0, MI, JL, FALSE, CH, FALSE, -1, -1 }, /* 27 */

  /* Test padding */

  { "10 10 0  0  MI JL F CH F -1 -1", LONGL, 10, 10, 0.0, 0.0, MI, JL, FALSE, CH, FALSE, -1, -1 }, /* 28 */
  { "10 10 .5 0  MI JC F CH F -1 -1", LONGL, 10, 10, 0.5, 0.0, MI, JL, FALSE, CH, FALSE, -1, -1 }, /* 29 */
  { "10 10 1  0  MI JR F CH F -1 -1", LONGL, 10, 10, 1.0, 0.0, MI, JL, FALSE, CH, FALSE, -1, -1 }, /* 30 */
  { "10 10 0  .5 MI JL F CH F -1 -1", LONGL, 10, 10, 0.0, 0.5, MI, JL, FALSE, CH, FALSE, -1, -1 }, /* 31 */
  { "10 10 .5 .5 MI JC F CH F -1 -1", LONGL, 10, 10, 0.5, 0.5, MI, JL, FALSE, CH, FALSE, -1, -1 }, /* 32 */
  { "10 10 1  .5 MI JR F CH F -1 -1", LONGL, 10, 10, 1.0, 0.5, MI, JL, FALSE, CH, FALSE, -1, -1 }, /* 33 */
  { "10 10 0  1  MI JL F CH F -1 -1", LONGL, 10, 10, 0.0, 1.0, MI, JL, FALSE, CH, FALSE, -1, -1 }, /* 34 */
  { "10 10 .5 1  MI JC F CH F -1 -1", LONGL, 10, 10, 0.5, 1.0, MI, JL, FALSE, CH, FALSE, -1, -1 }, /* 35 */
  { "10 10 1  1  MI JR F CH F -1 -1", LONGL, 10, 10, 1.0, 1.0, MI, JL, FALSE, CH, FALSE, -1, -1 }, /* 36 */
};

static void
create_labels (GtkBox *box)
{
  int i;

  for (i = 0; i < G_N_ELEMENTS (label_params); i++)
    {
      GtkWidget *label;
      const struct label_params *p;
      char buf[500];

      p = label_params + i;

      g_snprintf (buf, sizeof (buf), "%d %s\n%s", i, p->description, p->test);

      label = gtk_label_new (buf);
      gtk_misc_set_padding (GTK_MISC (label), p->xpad, p->ypad);
      gtk_misc_set_alignment (GTK_MISC (label), p->xalign, p->yalign);
      gtk_label_set_ellipsize (GTK_LABEL (label), p->ellipsize);
      gtk_label_set_justify (GTK_LABEL (label), p->justify);
      gtk_label_set_line_wrap (GTK_LABEL (label), p->line_wrap);
      gtk_label_set_line_wrap_mode (GTK_LABEL (label), p->line_wrap_mode);
      gtk_label_set_single_line_mode (GTK_LABEL (label), p->single_line_mode);
      gtk_label_set_width_chars (GTK_LABEL (label), p->width_chars);
      gtk_label_set_max_width_chars (GTK_LABEL (label), p->max_width_chars);

      gtk_box_pack_start (box, label, FALSE, TRUE, 0);
    }
}

static GtkWidget *
create_box (gboolean rtl)
{
  GtkWidget *sw;
  GtkWidget *box;

  sw = gtk_scrolled_window_new (NULL, NULL);
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
  gtk_widget_set_direction (sw, rtl ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);

  box = gtk_vbox_new (FALSE, 6);
  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw), box);

  create_labels (GTK_BOX (box));

  return sw;
}

int
main (int argc, char **argv)
{
  GtkWidget *window;
  GtkWidget *vbox;
  GtkWidget *label;
  GtkWidget *box;

  gtk_init (&argc, &argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  g_signal_connect (window, "destroy",
		    G_CALLBACK (gtk_main_quit), NULL);
  gtk_container_set_border_width (GTK_CONTAINER (window), 12);

  vbox = gtk_vbox_new (FALSE, 12);
  gtk_container_add (GTK_CONTAINER (window), vbox);

  /* LTR */

  label = gtk_label_new ("Left to right");
  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);

  box = create_box (FALSE);
  gtk_box_pack_start (GTK_BOX (vbox), box, TRUE, TRUE, 0);

  /* RTL */

  label = gtk_label_new ("Right to left");
  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);

  box = create_box (TRUE);
  gtk_box_pack_start (GTK_BOX (vbox), box, TRUE, TRUE, 0);

  gtk_widget_show_all (window);
  gtk_main ();

  return 0;
}
