/***********************************************************************
* starrule.c : Implementation of the rules for drawing stars.
***********************************************************************/
/***********************************************************************
* This file is part of SpaceChart.
* Copyright (C) 2000 Miguel Coca <e970095@zipi.fi.upm.es>
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
***********************************************************************/
#include <stdlib.h>
#include "../include/star.h"
#include "../include/star_selection.h"
#include "../include/star_draw_rules.h"
struct list_node
{
int priority;
star_selection_t* selection;
int is_radius;
int radius;
int is_rgb;
double rgb[3];
int show_name;
struct list_node* next;
};
struct st_star_draw_rules
{
int default_radius;
double default_rgb[3];
struct list_node* list;
};
/* Definition of local functions */
static int list_add( struct list_node** list, star_selection_t* selection,
int priority, int radius, double rgb[], int show_name );
static void list_find( struct list_node* list, star_t* star, int* have_radius,
int* radius, int* have_rgb, double rgb[],
int* show_name );
static void list_foreach( struct list_node* list, int min_priority,
int max_priority,
void (*function)( star_selection_t* selection,
int is_radius, int radius,
int is_rgb, double rgb[],
int show_name, void *data ),
void *data );
static void list_destroy( struct list_node* list );
/* Public functions */
star_drawing_rules_t* star_drawing_rules_new( int default_radius,
double default_rgb[] )
{
star_drawing_rules_t* rules;
if( ( rules = (star_drawing_rules_t*)
malloc( sizeof( struct st_star_draw_rules ) ) ) )
{
rules->default_radius = default_radius;
rules->default_rgb[0] = default_rgb[0];
rules->default_rgb[1] = default_rgb[1];
rules->default_rgb[2] = default_rgb[2];
rules->list = NULL;
}
return rules;
}
int star_drawing_rules_add( star_drawing_rules_t* rules,
star_selection_t* selection,
int priority,
int radius, double rgb[], int show_name )
{
return list_add( &(rules->list), selection, priority,
radius, rgb, show_name );
}
void star_drawing_rules_find( star_drawing_rules_t* rules,
star_t* star, int* radius, double rgb[],
int* show_name )
{
int have_radius = 0, have_rgb = 0;
*show_name = 0;
list_find( rules->list, star, &have_radius, radius,
&have_rgb, rgb, show_name );
if( !have_radius )
*radius = rules->default_radius;
if( !have_rgb )
{
rgb[0] = rules->default_rgb[0];
rgb[1] = rules->default_rgb[1];
rgb[2] = rules->default_rgb[2];
}
}
void star_drawing_rules_foreach( star_drawing_rules_t* rules,
int min_priority, int max_priority,
void (*function)( star_selection_t* selection,
int is_radius, int radius,
int is_rgb, double rgb[],
int show_name, void *data ),
void *data )
{
list_foreach( rules->list, min_priority, max_priority, function, data);
}
void star_drawing_rules_destroy( star_drawing_rules_t* rules )
{
list_destroy( rules->list );
free( rules );
}
/* Local Functions */
int list_add( struct list_node** list, star_selection_t* selection,
int priority, int radius, double rgb[], int show_name )
{
struct list_node* list_aux;
if( !*list )
{
if( ( *list = ( struct list_node* )
malloc( sizeof( struct list_node ) )) )
{
(*list)->priority = priority;
(*list)->selection = selection;
(*list)->show_name = show_name;
if( radius )
{
(*list)->is_radius = 1;
(*list)->radius = radius;
}
else
(*list)->is_radius = 0;
if( rgb )
{
(*list)->is_rgb = 1;
(*list)->rgb[0] = rgb[0];
(*list)->rgb[1] = rgb[1];
(*list)->rgb[2] = rgb[2];
}
else
(*list)->is_rgb = 0;
(*list)->next = NULL;
}
else
return 0;
}
else
{
if( priority < (*list)->priority )
{
list_aux = *list;
if( ( *list = ( struct list_node* )
malloc( sizeof( struct list_node ) )) )
{
(*list)->priority = priority;
(*list)->selection = selection;
(*list)->show_name = show_name;
if( radius )
{
(*list)->is_radius = 1;
(*list)->radius = radius;
}
else
(*list)->is_radius = 0;
if( rgb )
{
(*list)->is_rgb = 1;
(*list)->rgb[0] = rgb[0];
(*list)->rgb[1] = rgb[1];
(*list)->rgb[2] = rgb[2];
}
else
(*list)->is_rgb = 0;
(*list)->next = list_aux;
}
else
{
*list = list_aux;
return 0;
}
}
else
return list_add( &( (*list)->next ), selection,
priority, radius, rgb, show_name );
}
return 1;
}
void list_find( struct list_node* list, star_t* star, int* have_radius,
int* radius, int* have_rgb, double rgb[],
int* show_name )
{
if( list )
{
if( star_selection_match( list->selection, star ) )
{
if( list->is_radius && !*have_radius )
{
*radius = list->radius;
*have_radius = 1;
}
if( list->is_rgb && !*have_rgb )
{
rgb[0] = list->rgb[0];
rgb[1] = list->rgb[1];
rgb[2] = list->rgb[2];
*have_rgb = 1;
}
if( list->show_name )
*show_name = 1;
}
if( !*have_rgb || !*have_radius || !*show_name )
list_find( list->next, star, have_radius,
radius, have_rgb, rgb, show_name );
}
}
static void list_foreach( struct list_node* list, int min_priority,
int max_priority,
void (*function)( star_selection_t* selection,
int is_radius, int radius,
int is_rgb, double rgb[],
int show_name, void *data ),
void *data )
{
if( list )
{
if( list->priority >= min_priority )
{
if( list->priority <= max_priority )
{
function( list->selection, list->is_radius,
list->radius, list->is_rgb,
list->rgb, list->show_name, data );
list_foreach( list->next, min_priority,
max_priority, function, data );
}
}
else
list_foreach( list->next, min_priority, max_priority,
function, data );
}
}
static void list_destroy( struct list_node* list )
{
if( list )
{
list_destroy( list->next );
free( list );
}
}
syntax highlighted by Code2HTML, v. 0.9.1