/* The GIMP -- an image manipulation program
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * This is a plugin for the gimp.
 * Copyright (C) 1996 Alexander Schulz
 * New versions: http://www.uni-karlsruhe.de/~Alexander.Schulz/english/gimp/3d.html
 * Mail: Alexander.Schulz@stud.uni-karlsruhe.de
 *
 * The main and callback parts are modified from other plugins.
 * Thanks to the other programmers.
 */
#include "gimp.h"

/* Declare local functions.
 */
static void image_menu_callback (int, void *, void *);
static void text_callback (int, void *, void *);
static void ok_callback (int, void *, void *);
static void cancel_callback (int, void *, void *);
static void magiceye (Image, Image, int);

static char *prog_name;

static int dialog_ID, text_ID;

int
main (argc, argv)
     int argc;
     char **argv;
{
  Image src1, src2;
  char buf[10];
  int width;
  int group_ID;
  int temp_ID;
  int image_menu1_ID;
  int image_menu2_ID;
  int src1_ID, src2_ID;
  
  /* Save the program name so we can use it later in reporting errors
   */
  prog_name = argv[0];

  /* Call 'gimp_init' to initialize this filter.
   * 'gimp_init' makes sure that the filter was properly called and
   *  it opens pipes for reading and writing.
   */
  if (gimp_init (argc, argv))
    {
      src1 = src2 = 0;
      src1_ID = src2_ID = 0;
      width=100;

      /* Create a dialog.
       */
      dialog_ID = gimp_new_dialog ("Magic Eye");
      group_ID = gimp_new_row_group (dialog_ID, DEFAULT, NORMAL, "");
      image_menu1_ID = gimp_new_image_menu (dialog_ID, group_ID, 
					    IMAGE_CONSTRAIN_GRAY,
					    "Map Image");
      image_menu2_ID = gimp_new_image_menu (dialog_ID, group_ID, 
					    IMAGE_CONSTRAIN_ALL,
					    "Background");
     
      temp_ID = gimp_new_column_group (dialog_ID, group_ID, NORMAL, "");
      gimp_new_label (dialog_ID, temp_ID, "strip width:");
      sprintf(buf,"%i",width);
      text_ID = gimp_new_text (dialog_ID, temp_ID, buf);
      gimp_add_callback (dialog_ID, image_menu1_ID, image_menu_callback, &src1_ID);
      gimp_add_callback (dialog_ID, image_menu2_ID, image_menu_callback, &src2_ID);
      gimp_add_callback (dialog_ID, text_ID, text_callback, &width);
      gimp_add_callback (dialog_ID, gimp_ok_item_id (dialog_ID), ok_callback, 0);
      gimp_add_callback (dialog_ID, gimp_cancel_item_id (dialog_ID), cancel_callback, 0);
      
      if (gimp_show_dialog (dialog_ID))
	{
	  src1 = gimp_get_input_image (src1_ID);
	  src2 = (src2_ID != src1_ID) ? gimp_get_input_image (src2_ID) : src1;
	  
	  if (src1 && src2)
	    {
	      gimp_init_progress ("Creating 3d image");
	      magiceye (src1, src2, width);
	    }
	}

      /* Free the images.
       */
      if (src1)
	gimp_free_image (src1);
      if (src2)
	gimp_free_image (src2);

      /* Quit
       */
      gimp_quit ();
    }

  return 0;
}

static void
text_callback (item_ID, client_data, call_data)
  int item_ID;
  void *client_data;
  void *call_data;
{

  *((long *) client_data) = atoi(call_data);
}


static void
image_menu_callback (item_ID, client_data, call_data)
     int item_ID;
     void *client_data;
     void *call_data;
{
  *((long*) client_data) = *((long*) call_data);
}

static void
ok_callback (item_ID, client_data, call_data)
     int item_ID;
     void *client_data;
     void *call_data;
{
  gimp_close_dialog (dialog_ID, 1);
}

static void
cancel_callback (item_ID, client_data, call_data)
     int item_ID;
     void *client_data;
     void *call_data;
{
  gimp_close_dialog (dialog_ID, 0);
}

static void
magiceye (src1, src2, strip_width)
     Image src1, src2;
     int strip_width;
{
  Image dest;
  ImageType dest_type;
  unsigned char *src1p;
  unsigned char *src2p;
  unsigned char *destp;
  unsigned char *cmap;
  unsigned char *savep;
  long src1_width, src1_height;
  long src2_width, src2_height;
  long src1_channels;
  long src2_channels;
  long dest_channels;
  int src1r, src1g, src1b;
  int src2r, src2g, src2b;
  int destr, destg, destb;
  int i, j, number, hoehe, x;

  src1p = gimp_image_data (src1);
  src2p = gimp_image_data (src2);

  src2_width = gimp_image_width (src2);
  src2_height = gimp_image_height (src2);
  src1_width = gimp_image_width (src1);
  src1_height = gimp_image_height (src1);
  
  src2_channels = gimp_image_channels (src2);

  dest_channels = src2_channels;
  dest_type = gimp_image_type(src2);
  
  dest = gimp_new_image (0, src1_width, src1_height, dest_type);
  destp = gimp_image_data (dest);
  savep = destp;

  if (dest_type!=RGB_IMAGE)
    {
      cmap = gimp_image_cmap(src2);
      number = gimp_image_colors(src2);
      gimp_set_image_colors(dest,cmap,number);
    }


  for (i = 0; i < src1_height; i++)
    {
      for (j = 0; j < src1_width*dest_channels; j++)
	{
	  *destp++ = *(src2p+((j%(strip_width*dest_channels))+src2_width*i*dest_channels));
	}
      if ((i % 5) == 0)
	gimp_do_progress (i, src1_height);
    }
    
  destp = savep;
  gimp_do_progress(0,1);
  for (j = strip_width; j < src1_width; j++)
    {
      for (i = 0; i < src1_height; i++)
	{
	  hoehe=src1p[i*src1_width*1+j*1] / 50;
	  for (x=0; x<dest_channels; x++)
	    {
	       destp[(i*src1_width+j-hoehe)*dest_channels+x] =
	         destp[(i*src1_width+j-strip_width)*dest_channels+x];
	    }
	}
      if ((j % 5) == 0)
	gimp_do_progress (j, src1_width);
    }

  gimp_display_image (dest);
  gimp_update_image (dest);
  gimp_free_image (dest);
}

