/* Functions: symbol_save, symbol_draw 
**
** Author: Radim Blazek
*/

#include <grass/Vect.h>
#include <grass/symbol.h>
#include "clr.h"
#include "ps_info.h"
#include "local_proto.h"
#include "vector.h"

/* draw chain */
int 
draw_chain ( SYMBCHAIN *chain, double s ) 
{ 
    int k, l;
    char *mvcmd;
    SYMBEL *elem;

    for ( k = 0; k < chain->count; k++ ) {
	elem = chain->elem[k];
	switch ( elem->type ) {
	    case S_LINE:
		for (l = 0; l < elem->coor.line.count; l++) {
		    if ( k == 0 && l == 0 ) mvcmd = "M";
		    else mvcmd = "LN";
		    fprintf(PS.fp, "%.4f %.4f %s\n", 
			s * elem->coor.line.x[l],
			s * elem->coor.line.y[l],
			mvcmd);
		}
		break;
	    case S_ARC:
		if ( elem->coor.arc.clock ) mvcmd = "arcn"; 
		else mvcmd = "arc";
		fprintf(PS.fp, "%.4f %.4f %.4f %.4f %.4f %s\n", 
			s * elem->coor.arc.x,
			s * elem->coor.arc.y,
			s * elem->coor.arc.r,
			elem->coor.arc.a1, elem->coor.arc.a2,
			mvcmd );
		break;
	}
    }

    return 0;
}

int 
symbol_draw ( char *name, double x, double y, double size, double rotate, double width ) 
{
    fprintf( PS.fp, "gsave\n");
    fprintf( PS.fp, "%.5f %.5f translate\n", x, y);
    fprintf( PS.fp, "%.5f %.5f scale\n", size, size);
    fprintf(PS.fp, "%.5f rotate\n", rotate);
    fprintf(PS.fp, "%.8f W\n", width / size );
    fprintf(PS.fp, "%s\n", name);
    fprintf( PS.fp, "grestore\n");

    return 0;
}

/* store symbol in PS file, scaled to final size and drawn with final colors */
int 
symbol_save ( SYMBOL *Symb, PSCOLOR *color, PSCOLOR *fcolor, char *name )
{
    SYMBPART *part; 
    SYMBCHAIN *chain;
    int points;
    int i, j;
    double s, xo[4], yo[4];

    points = 4;
    xo[0] =  0.0;  yo[0] =  0.5; xo[1] = -0.5;  yo[1] =  0.0;
    xo[2] =  0.0;  yo[2] = -0.5; xo[3] =  0.5;  yo[3] =  0.0;

    s = 1;

    fprintf(PS.fp, "\n/%s {\n", name);
    if ( Symb != NULL ) {
        s *= Symb->scale;
	for ( i = 0; i < Symb->count; i++ ) { 
	    part = Symb->part[i];
	    switch ( part->type ) {
		case S_POLYGON: 
		    fprintf(PS.fp, "NP\n"); /* Start ring */
		    for ( j = 0; j < part->count; j++ ) { /* RINGS */
			chain = part->chain[j];
                        draw_chain ( chain, s );
			fprintf(PS.fp, "CP\n"); /* Close one ring */
		    }
		    /* Fill */
		    if ( part->fcolor.color == S_COL_DEFAULT && !color_none(fcolor) ) {
			    set_ps_color( fcolor );
			    fprintf(PS.fp, "F\n"); /* Fill polygon */
		    } else if ( part->fcolor.color == S_COL_DEFINED ) {
			    fprintf(PS.fp, "%.3f %.3f %.3f C\n", part->fcolor.fr,
					      part->fcolor.fg, part->fcolor.fb);
			    fprintf(PS.fp, "F\n");
		    }
		    /* Outline */
		    if ( part->color.color == S_COL_DEFAULT && !color_none(color) ) {
			set_ps_color( color );
			fprintf(PS.fp, "D\n"); /* Draw boundary */
		    } else if ( part->color.color == S_COL_DEFINED ) { 
		        fprintf(PS.fp, "%.3f %.3f %.3f C\n", part->color.fr,
					      part->color.fg, part->color.fb);
			fprintf(PS.fp, "D\n");
		    }
		    break;
		case S_STRING: /* string has 1 chain */
		    if ( part->color.color != S_COL_NONE ) {
			fprintf(PS.fp, "NP\n"); 
			chain = part->chain[0];
			draw_chain ( chain, s );
			/* Color */
			if ( part->color.color == S_COL_DEFAULT && !color_none(color) ) {
			    set_ps_color( color );
			    fprintf(PS.fp, "D\n");
			} else {
			    fprintf(PS.fp, "%.3f %.3f %.3f C\n", part->color.fr,
					      part->color.fg, part->color.fb);
			    fprintf(PS.fp, "D\n");
			}
		    }
		    break;
	    }
	}
    } else { 
	fprintf(PS.fp, "%.4f %.4f NM\n", s * xo[0], s * yo[0]);
	for (j = 1; j < points; j++) 
	   fprintf(PS.fp, "%.4f %.4f LN\n", s * xo[j], s * yo[j]);
	fprintf(PS.fp, "CP\n");

	set_ps_color( fcolor );
	fprintf(PS.fp, "F\n");
        set_ps_color( color );
	fprintf(PS.fp, "D\n");
    }
    fprintf(PS.fp, "} def\n");

    return 0;
}
