/* @Hdr */

#include <grape.h>

/* @DOC symmetry8 */

/* grape-methode "timebar"
 *  
 * Call              : GRAPE(timescene,"timebar")(tmin,tmax,hv)
 * Call              : GRAPE(timescene,"timebar-send")()
 * 
 * Parameters        : TIMESCENE *timescene; float tmin,tmax; int hv;
 *             
 * Description       : erzeugt neue timescene mit timebar geometrie
 *
 * Keywords          : 
 *
 * Author            : alfred schmidt
 *
 * Copyright (c) 1995     by Universitaet Freiburg
 *                           Institut fuer Angewandte Mathematik
 *                           D-79104 Freiburg
 *
 * history           : 16.02.95 neu erstellt
 */


/* @GRAPE 

 METHOD(TimeScene[timebar-hv])
 METHOD(TimeScene[timebar-h])
 METHOD(TimeScene[timebar-v])
 METHOD(TimeScene[timebar-h-send])
 METHOD(TimeScene[timebar-v-send])
 METHOD(Triang2d[display-timebar])

*/   


/* @SRC tsc_tbar.c */

static int   tbar_np = 8;
static int   tbar_ne = 4;
#define TB0 0.0
#define TB1 1.0
#define TBW 0.05
#define TBw 0.01
#define TBz -0.05

static double vx[8]=  {TBW, 0.0, TBW, 0.0, TBw, 0.0, TBw, 0.0};
static double vy1[8]= {TB0, TB0, TB0, TB0, TB0, TB0, TB1, TB1};
static double vy2[8]= {TB0, TB0, TB1, TB1, TB0, TB0, TB1, TB1};
static double vz[8]=  {0.0, 0.0, 0.0, 0.0, 0.0, TBz, 0.0, TBz};

static double hx1[8]= {TB0, TB0, TB0, TB0, TB0, TB0, TB1, TB1};
static double hx2[8]= {TB0, TB0, TB1, TB1, TB0, TB0, TB1, TB1};
static double hy[8]=  {0.0, TBW, 0.0, TBW, 0.0, TBw, 0.0, TBw};
static double hz[8]=  {0.0, 0.0, 0.0, 0.0, 0.0, TBz, 0.0, TBz};

static INT3 tbar_vertex[4]   ={{0,2,3}, {0,3,1}, {4,7,6}, {4,5,7}};
static INT3 tbar_neighbour[4]={{-1,1,-1}, {-1,-1,0}, {-1,-1,3}, {-1,2,-1}};

static double s_tmin,s_tmax;
static int    s_horiz;

TIMESCENE *timescene_hv_timebar(double tmin, double tmax, int horiz)
{ 
  TIMESCENE *tsc, *tsc1;
  TRIANG2D  *tr1, *tr2;
  int i,j;
  
  tsc = (TIMESCENE *)START_METHOD(G_INSTANCE);
  ASSURE(tsc, "can't manage classes", END_METHOD(NIL));

  printf("timescene_hv_timebar: tmin=%f, tmax=%f, horiz=%d\n",tmin,tmax,horiz);

  s_tmin = tmin;
  s_tmax = tmax;
  s_horiz = horiz;

  tsc1 = (TIMESCENE *)GRAPE(TimeScene,"new-instance")("timebar");
  tr1 = (TRIANG2D *)GRAPE(Triang2d,"new-instance")("timebar1");
  tr2 = (TRIANG2D *)GRAPE(Triang2d,"new-instance")("timebar2");
  
  ASSURE(tsc1 && tr1 && tr2, "can't allocate new instances", END_METHOD(NIL));

  tr1->max_number_of_points = tr1->number_of_points = tbar_np;
  tr1->max_number_of_elements = tr1->number_of_elements = tbar_ne;
  tr2->max_number_of_points = tr2->number_of_points = tbar_np;
  tr2->max_number_of_elements = tr2->number_of_elements = tbar_ne;
  tr1->vertex = tr2->vertex = tbar_vertex;
  tr1->neighbour = tr2->neighbour = tbar_neighbour;

  for (i=0; i<4; i++) 
    for (j=0; j<4; j++)
      tsc1->object_trans[i][j] = (i==j) ? 1.0 : 0.0;
  tsc1->matrix_flag = G_MATRIX_PROJECT;


  if (horiz) { /* horizontal */
    tr1->x = hx1;
    tr1->y = hy;
    tr1->z = hz;
    tr2->x = hx2;
    tr2->y = hy;
    tr2->z = hz;
    tsc1->object_trans[0][3] = -0.5;
    tsc1->object_trans[1][3] = -0.5;
  }
  else {
    tr1->x = vx;
    tr1->y = vy1;
    tr1->z = vz;
    tr2->x = vx;
    tr2->y = vy2;
    tr2->z = vz;
    tsc1->object_trans[0][3] =  0.8;
    tsc1->object_trans[1][3] = -0.5;
  }

  tsc1->dynamic = (void *)GRAPE(TimeStep,"put")(tr1,tr1,tmin);
  tsc1->dynamic = (void *)GRAPE(tsc1->dynamic,"put")(tr2,tr2,tmax);
  tsc1->method_name = "display-timebar";
  tsc1->sync = 1;

  tsc1->next_scene = tsc->next_scene;
  tsc->next_scene = (SCENE *)tsc1;


  END_METHOD(tsc1);
}

TIMESCENE *timescene_htimebar(double tmin, double tmax)
{
  return(timescene_hv_timebar(tmin, tmax, 1));
}

TIMESCENE *timescene_vtimebar(double tmin, double tmax)
{
  return(timescene_hv_timebar(tmin, tmax, 0));
}





TIMESCENE *timescene_hv_timebar_send(int horiz)
{
  double tmin,tmax;
  TIMESCENE *tsc;
  TIMESTEP  *step;
  
  tsc = (TIMESCENE *)START_METHOD(G_INSTANCE);
  ASSURE(tsc, "can't manage classes", END_METHOD(NIL));

  step = (TIMESTEP *)tsc->dynamic;

  if (step) {
    tmin =  1.0E30;
    tmax = -1.0E30;
    while (step->pre_step) {
      step = step->pre_step;
    }
    while (step) {
      if (step->time < tmin) tmin = step->time;
      if (step->time > tmax) tmax = step->time;
      step = step->post_step;
    }
  }
  else
  {
    tmin = 0.0;
    tmax = 1.0;
  }

  tsc = (TIMESCENE *)GRAPE(tsc, "timebar-hv")(tmin, tmax, horiz);
  END_METHOD(tsc);
}

TIMESCENE *timescene_htimebar_send()
{
  return(timescene_hv_timebar_send(1));
}

TIMESCENE *timescene_vtimebar_send()
{
  return(timescene_hv_timebar_send(0));
}

TRIANG2D *display_timebar()
{
  TRIANG2D *t;
  MATRIX44 m_backup,v_backup;
  static MATRIX44 id={{1.,0.,0.,0.},{0.,1.,0.,0.},{0.,0.,1.,0.},{0.,0.,0.,1.}};
  GRAPHICDEVICE *dev;
  char s[20];
  static VEC3 sp1h={0.0, -0.1, 0.0};
  static VEC3 sp1v={-0.1, -0.1, 0.0};
  static VEC3 sp2h={0.9, -0.1, 0.0};
  static VEC3 sp2v={-0.1, 1.05, 0.0};

  t = (TRIANG2D *)START_METHOD(G_INSTANCE);
  ASSURE(t, "can't manage classes", END_METHOD(NIL));

  dev = (GRAPHICDEVICE *)GRAPE(GraphicDevice,"get-stddev")();
  dev->transform(G_MODE_GET,G_MATRIX_MODEL,m_backup);
  dev->transform(G_MODE_GET,G_MATRIX_VIEW, v_backup);
  dev->transform(G_MODE_SET,G_MATRIX_MODEL,id);
  dev->transform(G_MODE_SET,G_MATRIX_VIEW, id);

  GRAPE(t,"display")();

  sprintf(s,"%8.4f",s_tmin);
  s[8] = s[9] = 0;
  if (s_horiz)
    dev->text(sp1h, s);
  else
    dev->text(sp1v, s);
    

  sprintf(s,"%8.4f",s_tmax);
  s[8] = s[9] = 0;
  if (s_horiz)
    dev->text(sp2h, s);
  else
    dev->text(sp2v, s);

  dev->transform(G_MODE_SET,G_MATRIX_MODEL,m_backup);
  dev->transform(G_MODE_SET,G_MATRIX_VIEW, v_backup);

  END_METHOD(t);
}




void def_timebar_methods()
{
  GRAPE(TimeScene,"add-method")("timebar-h-send", timescene_htimebar_send);
  GRAPE(TimeScene,"add-method")("timebar-v-send", timescene_vtimebar_send);
  GRAPE(TimeScene,"add-method")("timebar-h", timescene_htimebar);
  GRAPE(TimeScene,"add-method")("timebar-v", timescene_vtimebar);
  GRAPE(TimeScene,"add-method")("timebar-hv", timescene_hv_timebar);
  GRAPE(Triang2d,"add-method")("display-timebar", display_timebar);

  return;
}

