/**********************************************************************
 
	Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	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.

**********************************************************************/



#include	"u_math.h"
#include	"gbview.h"
#include	"win_flame.h"
#include	"resource.h"



void
calc_pitch_ln(GBVIEW_FLAME * gf,int flag)
{
GB_POINT pp;
REAL1 reso;
REAL1 x_sign,y_sign;

	if ( gf->flame_base->draw->c.geometory_type & GT_A_X_REV ) 
		x_sign = -1;
	else	x_sign = 1;
	if ( gf->flame_base->draw->c.geometory_type & GT_A_Y_REV )
		y_sign = 1;
	else	y_sign = -1;

	pp.x = ((REAL1)gf->win_width)/2;
	pp.y = ((REAL1)gf->win_height)/2;
	reso = 1;
	if ( flag == 0 ) {
		map_from_flame(
			&gf->flame_base_display_map,
			&pp,
			&reso,
			1);
		gf->flame_base_center = pp;
	}
       	gf->flame_base_display_map.d.ln.reverse.org.x =
		(-(cos(gf->flame_base_rotate)*gf->win_width
				+
		  sin(gf->flame_base_rotate)*gf->win_height)
			/(2*gf->flame_base_resolution)
		+ x_sign*gf->flame_base_center.x) * x_sign;
	gf->flame_base_display_map.d.ln.reverse.org.y =
		(-(-sin(gf->flame_base_rotate)*gf->win_width
				+
		  cos(gf->flame_base_rotate)*gf->win_height)
			/(2*gf->flame_base_resolution)
		+ y_sign*gf->flame_base_center.y) * y_sign;
	gf->flame_base_display_map.d.ln.reverse.matrix[0][0] =
		cos(gf->flame_base_rotate)/gf->flame_base_resolution*x_sign;
	gf->flame_base_display_map.d.ln.reverse.matrix[0][1] =
		sin(gf->flame_base_rotate)/gf->flame_base_resolution*x_sign;
	gf->flame_base_display_map.d.ln.reverse.matrix[1][0] =
		-sin(gf->flame_base_rotate)/gf->flame_base_resolution*y_sign;
	gf->flame_base_display_map.d.ln.reverse.matrix[1][1] =
		cos(gf->flame_base_rotate)/gf->flame_base_resolution*y_sign;

	gf->flame_base_display_map.d.ln.forward.org.x =
		((REAL1)gf->win_width)/2 -
		(cos(gf->flame_base_rotate)*gf->flame_base_center.x*x_sign
		- sin(gf->flame_base_rotate)*gf->flame_base_center.y*y_sign)*
			gf->flame_base_resolution;
	gf->flame_base_display_map.d.ln.forward.org.y =
		((REAL1)gf->win_height)/2 -
		(sin(gf->flame_base_rotate)*gf->flame_base_center.x*x_sign
		+ cos(gf->flame_base_rotate)*gf->flame_base_center.y*y_sign)*
			gf->flame_base_resolution;
	gf->flame_base_display_map.d.ln.forward.matrix[0][0] =
		cos(gf->flame_base_rotate)*gf->flame_base_resolution*x_sign;
	gf->flame_base_display_map.d.ln.forward.matrix[0][1] =
		-sin(gf->flame_base_rotate)*gf->flame_base_resolution*y_sign;
	gf->flame_base_display_map.d.ln.forward.matrix[1][0] =
		sin(gf->flame_base_rotate)*gf->flame_base_resolution*x_sign;
	gf->flame_base_display_map.d.ln.forward.matrix[1][1] =
		cos(gf->flame_base_rotate)*gf->flame_base_resolution*y_sign;

	gf->flame_base_display_map.d.ln.forward_reso_rate = 1;
	gf->flame_base_display_map.d.ln.reverse_reso_rate = 1;

	gf->flame_base_display_map.type = MHT_LINEAR;
	gf->flame_base_display_map.dir = MHD_REVERSE;
}

void
calc_pitch_pp(GBVIEW_FLAME * gf,int flag)
{
GB_POINT pp;
REAL1 reso,phi;
REAL1 x_sign,y_sign;
RESOURCE * r;
int er;

	r = gf->flame_base->draw;
	if ( r->c.geometory_type & GT_A_X_REV ) 
		x_sign = -1;
	else	x_sign = 1;
	if ( r->c.geometory_type & GT_A_Y_REV )
		y_sign = -1;
	else	y_sign = 1;
	gf->flame_base_display_map.d.pp.forward_rate
		= conv_unit(&er,
			r->h.cu.uenv,
			1,
			r->h.cu.unit,
			l_string(std_cm,"rad"));

	if ( flag == 0 ) {
		pp.x = ((REAL1)gf->win_width)/2;
		pp.y = ((REAL1)gf->win_height)/2;
		reso = 1;
		map_from_flame(
			&gf->flame_base_display_map,
			&pp,
			&reso,
			1);
		gf->flame_base_center = pp;
	}


	gf->flame_base_display_map.d.pp.lambda
		= gf->flame_base_center.x * x_sign;
	gf->flame_base_display_map.d.pp.phi
		= phi = gf->flame_base_center.y * y_sign;

	phi = conv_unit(&er,
			r->h.cu.uenv,
			phi,
			r->h.cu.unit,
			l_string(std_cm,"rad"));
	reso = conv_unit(&er,
			r->h.cu.uenv,
			gf->flame_base_resolution,
			reso_c_unit(&r->h.cu),
			l_string(std_cm,"dot/rad"));

       	gf->flame_base_display_map.d.pp.reverse_sur.org.x =
		-(cos(gf->flame_base_rotate)*gf->win_width
				+
		  sin(gf->flame_base_rotate)*gf->win_height)
			/(2*reso);
	gf->flame_base_display_map.d.pp.reverse_sur.org.y =
		-(-sin(gf->flame_base_rotate)*gf->win_width
				+
		  cos(gf->flame_base_rotate)*gf->win_height)
			/(2*reso);
	gf->flame_base_display_map.d.pp.reverse_sur.matrix[0][0] =
		cos(gf->flame_base_rotate)/reso;
	gf->flame_base_display_map.d.pp.reverse_sur.matrix[0][1] =
		sin(gf->flame_base_rotate)/reso;
	gf->flame_base_display_map.d.pp.reverse_sur.matrix[1][0] =
		-sin(gf->flame_base_rotate)/reso;
	gf->flame_base_display_map.d.pp.reverse_sur.matrix[1][1] =
		cos(gf->flame_base_rotate)/reso;

	gf->flame_base_display_map.d.pp.reverse_vol[0][0] = 1;
	gf->flame_base_display_map.d.pp.reverse_vol[0][1] = 0;
	gf->flame_base_display_map.d.pp.reverse_vol[0][2] = 0;
	gf->flame_base_display_map.d.pp.reverse_vol[1][0] = 0;
	gf->flame_base_display_map.d.pp.reverse_vol[1][1] = cos(phi);
	gf->flame_base_display_map.d.pp.reverse_vol[1][2] = -sin(phi);
	gf->flame_base_display_map.d.pp.reverse_vol[2][0] = 0;
	gf->flame_base_display_map.d.pp.reverse_vol[2][1] = sin(phi);
	gf->flame_base_display_map.d.pp.reverse_vol[2][2] = cos(phi);


	gf->flame_base_display_map.d.pp.forward_sur.org.x =
		((REAL1)gf->win_width)/2;
	gf->flame_base_display_map.d.pp.forward_sur.org.y =
		((REAL1)gf->win_height)/2;
	gf->flame_base_display_map.d.pp.forward_sur.matrix[0][0] =
		cos(gf->flame_base_rotate)*reso;
	gf->flame_base_display_map.d.pp.forward_sur.matrix[0][1] =
		-sin(gf->flame_base_rotate)*reso;
	gf->flame_base_display_map.d.pp.forward_sur.matrix[1][0] =
		sin(gf->flame_base_rotate)*reso;
	gf->flame_base_display_map.d.pp.forward_sur.matrix[1][1] =
		cos(gf->flame_base_rotate)*reso;

	gf->flame_base_display_map.d.pp.forward_vol[0][0] = 1;
	gf->flame_base_display_map.d.pp.forward_vol[0][1] = 0;
	gf->flame_base_display_map.d.pp.forward_vol[0][2] = 0;
	gf->flame_base_display_map.d.pp.forward_vol[1][0] = 0;
	gf->flame_base_display_map.d.pp.forward_vol[1][1] = cos(phi);
	gf->flame_base_display_map.d.pp.forward_vol[1][2] = sin(phi);
	gf->flame_base_display_map.d.pp.forward_vol[2][0] = 0;
	gf->flame_base_display_map.d.pp.forward_vol[2][1] = -sin(phi);
	gf->flame_base_display_map.d.pp.forward_vol[2][2] = cos(phi);

	gf->flame_base_display_map.type = MHT_PP;
	gf->flame_base_display_map.dir = MHD_REVERSE;

}

void
_change_table(GBVIEW_FLAME * gf,int geo_type)
{
WIN_FLAME * wf;
	for ( wf = gf->flame ; wf ; wf = wf->next )
		_change_win_flame(gf,wf,geo_type,0);
}

void
_calc_pitch(GBVIEW_FLAME * gf,int flag)
{
	if ( gf->flame_base == 0 || gf->flame_base->draw == 0 )
		return;
	switch ( gf->flame_base->draw->c.geometory_type & GT_T_MASK ) {
	case GT_T_2D:
		calc_pitch_ln(gf,flag);
		_change_table(gf,GT_T_2D>>GT_T_SHIFT);
		break;
	case GT_T_GLOBE_SUR:
		calc_pitch_pp(gf,flag);
		_change_table(gf,GT_T_GLOBE_SUR>>GT_T_SHIFT);
		break;
	default:
		er_panic("calc_pitch(1)");
	}
}

void
calc_pitch(GBVIEW_FLAME * gf,int flag)
{
	wf_lock(gf);
	_calc_pitch(gf,flag);
	wf_unlock(gf);
}

void
center_check(GBVIEW_FLAME * gf)
{
	if ( gf->flame_base_center.x > 151 )
		er_panic("center");
	printf("CENTER %f\n",gf->flame_base_center.x);
}
