/****************************************************************************
 *
 * MODULE:       d.rgb
 * AUTHOR(S):    Glynn Clements <glynn gclements.plus.com> (original contributor)
 *               Roberto Flor <flor itc.it>, 
 *               Bernhard Reiter <bernhard intevation.de>, 
 *               Hamish Bowman <hamish_b yahoo.com>, 
 *               Markus Neteler <neteler itc.it>, 
 *               Radim Blazek <radim.blazek gmail.com>
 * PURPOSE:      Combine three rasters to form a colour image using red, green,
 *               and blue display channels
 * COPYRIGHT:    (C) 2001-2007, 2010 by the GRASS Development Team
 *
 *               This program is free software under the GNU General Public
 *               License (>=v2). Read the file COPYING that comes with GRASS
 *               for details.
 *
 *****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <grass/gis.h>
#include <grass/display.h>
#include <grass/raster.h>
#include <grass/glocale.h>

struct band
{
    struct Option *opt;
    int file;
    int type;
    void *array;
    struct Colors colors;
};

static char *const color_names[3] = { "red", "green", "blue" };

int main(int argc, char **argv)
{
    struct band B[3];
    char *mapset;
    int row;
    int next_row;
    struct Cell_head window;
    struct GModule *module;
    struct Flag *flag_o;
    struct Flag *flag_x;
    int t, b, l, r;
    int i;

    G_gisinit(argv[0]);

    module = G_define_module();
    module->keywords = _("display, raster, RGB");
    module->description =
	_("Displays three user-specified raster maps "
	  "as red, green, and blue overlays in the active graphics frame.");

    flag_o = G_define_flag();
    flag_o->key = 'o';
    flag_o->description = _("Overlay (non-null values only)");
    
    flag_x = G_define_flag();
    flag_x->key = 'x';
    flag_x->description = _("Don't add to list of commands in monitor");

    for (i = 0; i < 3; i++) {
	char buff[80];

	sprintf(buff, _("Name of raster map to be used for '%s'"),
		color_names[i]);

	B[i].opt = G_define_standard_option(G_OPT_R_MAP);
	B[i].opt->key = G_store(color_names[i]);
	B[i].opt->description = G_store(buff);
    }

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    /* Do screen initializing stuff */
    if (R_open_driver() != 0)
	G_fatal_error(_("No graphics device selected"));
    
    D_get_screen_window(&t, &b, &l, &r);
    D_set_overlay_mode(flag_o->answer);
    D_cell_draw_setup(t, b, l, r);

    for (i = 0; i < 3; i++) {
	/* Get name of layer to be used */
	char *name = B[i].opt->answer;

	mapset = G_find_cell2(name, "");
	if (mapset == NULL)
	    G_fatal_error(_("Raster map <%s> not found"), name);

	/* Make sure map is available */
	if ((B[i].file = G_open_cell_old(name, mapset)) == -1)
	    G_fatal_error(_("Unable to open raster map <%s>"), name);

	B[i].type = G_get_raster_map_type(B[i].file);

	/* Reading color lookup table */
	if (G_read_colors(name, mapset, &B[i].colors) == -1)
	    G_fatal_error(_("Color file for <%s> not available"), name);

	B[i].array = G_allocate_raster_buf(B[i].type);
    }

    /* read in current window */
    G_get_window(&window);

    next_row = 0;
    for (row = 0; row < window.rows;) {
	G_percent(row, window.rows, 5);

	for (i = 0; i < 3; i++)
	    if (G_get_raster_row(B[i].file, B[i].array, row, B[i].type) < 0)
		G_fatal_error(_("Error reading row of data"));

	if (row == next_row)
	    next_row = D_draw_raster_RGB(next_row,
					 B[0].array, B[1].array, B[2].array,
					 &B[0].colors, &B[1].colors,
					 &B[2].colors, B[0].type, B[1].type,
					 B[2].type);
	else if (next_row > 0)
	    row = next_row;
	else
	    break;
    }
    G_percent(window.rows, window.rows, 5);
    D_cell_draw_end();

    /* Close down connection to window driver */
    if (!flag_x->answer)
	D_add_to_list(G_recreate_command());

    R_close_driver();

    /* Close the raster maps */
    for (i = 0; i < 3; i++)
	G_close_cell(B[i].file);

    exit(EXIT_SUCCESS);
}
