/* 
 * Thomas Pantzer: homeo_demo.cc, v0.4.7  8.6.99 16:32 
 * 
 * 
 * Copyright 1999 by Thomas Pantzer
 * 
 * Permission to use, copy, modify, and distribute this software for noncommercial 
 * use and without fee is hereby granted, provided that the above copyright notice 
 * appear in all copies and that both that copyright notice and this permission 
 * notice appear in supporting documentation, and that the name of the Author not be 
 * used in advertising or publicity pertaining to distribution of the software 
 * without specific, written prior permission. The Author makes no representations about
 * the suitability of this software for any purpose.  It is provided "as is" 
 * without expressed or implied warranty. 
 * 
 * 
 * pantec@isys2.informatik.uni-leipzig.de   (Thomas Pantzer) 
 * 
 */




#include <forms.h>
#include <math.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

#include "copyright.h"

#include "new_panel.h"
#include "trigonom.h"
#include "neuronal_demo.h"

#include "t_runtime_obj.h"

#include "graphix.h"
#include "stuff.h"
#include "user.h"

#include "CrashTest_demo.h"


#define _homeo_DEMO_G
#include "homeo_demo.h"


#define homeo_nBoxes	7
#define homeo_nSliders	8

#define _sl_num	2

#define _sl_freq	(0+_sl_num)
#define _sl_learn	(1+_sl_num)
#define _sl_horiz	(2+_sl_num)
#define _sl_sinamp	(3+_sl_num)
#define _sl_speed	(4+_sl_num)
#define _sl_damp	(5+_sl_num)
#define _sl_batch	(6+_sl_num)
#define _sl_ampl	(7+_sl_num)

#define _bt_disturb	(_bt_num)
#define _bt_random	(_bt_num+1)
#define _bt_wakeup	(_bt_num+2)
// #define _bt_uselight	(_bt_num+3)
#define _bt_extrap1	(_bt_num+3)
#define _bt_extrap2	(_bt_num+4)
#define _bt_extrap3	(_bt_num+5)
#define _bt_extrap4	(_bt_num+6)

//#define _bt_extrap5	(_bt_num+7)
//#define _bt_extrap6	(_bt_num+8)




char homeo_boxes[homeo_nBoxes][32] = {"add noise\0"
				     ,"init random/ load\0"
				     ,"wakeup\0"
//				     ,"with ambient\0"
				     ,"ired C,Z,mirror(Z)\0"
				     ,"ired C,Z,next(Z)\0"
				     ,"ambl C,Z,mirror(Z)\0"
				     ,"ambl C,Z,next(Z)\0"
				     };

//				     ,"c*(X[i]-X[i+1])\0"
//				     ,"c*(X[i]*X[j])\0"
//				     ,"c*(X[i]*X[j])\0"

char homeo_sliders[homeo_nSliders][16] = {"freq.\0",
					"learn\0",
					"horizont\0",
					"störung\0",
					"speed\0",
					"damping\0","batch\0","ampl.\0"};


void t_homeo_demo::Init(RobotContext *robot)
{
	char *cb_pointers[homeo_nBoxes];
	char *sl_pointers[homeo_nSliders];

	for (int i=0; i<homeo_nBoxes; i++)
          cb_pointers[i]  = &homeo_boxes[i][0];

	for (int i=0; i<homeo_nSliders; i++)
          sl_pointers[i]  = &homeo_sliders[i][0];

	int pro = 0; 
	pro |= _p_control;	//  does something to control the robot
	pro |= _p_calc;		//  needs calculations
	pro |= _p_extras;	//  uses user settable parameters
	pro |= _p_logctl;	//  uses user settable parameters

	t_runtime_object::Init("Homeo",robot,pro,
		homeo_nSliders,homeo_nBoxes,0,
		sl_pointers,cb_pointers,NULL);

	Poly = new t_Polynom;
	Poly->Init(MAX_POLY_PARMS,n_sensors);

	for (int i=0; i<8; i++)
	    Poly->UseVal(0,i,true);

	g_radius.Init(t_depth);
	sinus.Init(t_depth);
	Sin2.Init(t_depth);


	for (int i=0; i<n_sensors; i++)
	  {
	   Sensor[i].Init(t_depth); 
	   q[i].Init(14);	
	  } 

	was_online = true;
	free_steps = 0;
}


void t_homeo_demo::button_cb(FL_OBJECT *ob,long data)
{	// dummy call
	// prevent "not overloaded" errors
	switch(data)
	  {
	   // add your cases here
	   case _bt_extrap1:
	   case _bt_extrap2:
	     {
	      int p = 1+ data - _bt_extrap1;
	      
	      if (fl_get_button(ob))
	         for (int i=0; i<8; i++)
	            Poly->UseVal(p,i,true);
	       else 
	         for (int i=0; i<8; i++)
	            Poly->UseVal(p,i,false);
	     } 
	     break;

	   case _bt_extrap3:
	   case _bt_extrap4:
//	   case _bt_extrap5:
//	   case _bt_extrap6:
	     {
	      int p = 1+ data - _bt_extrap4;
	      
	      uselight = fl_get_button(ob);	
	      if (uselight)
	         for (int i=8; i<16; i++)
	            Poly->UseVal(p,i,true);
	       else 
	         for (int i=8; i<16; i++)
	            Poly->UseVal(p,i,false);
	     } 
	     break;

	   // rest ist handled by parent object
	   case 0:
	   case 1:
	   case 2:
	   default:
	     t_runtime_object::button_cb(ob,data);
	     break; 	
	  }
}

void t_homeo_demo::slider_cb(FL_OBJECT *ob,long data)
{	// dummy call
	// prevent "not overloaded" errors
	switch(data)
	  {
	   case _sl_speed:
	     robot_netspeed = fl_get_slider_value(ob);
	     break;

	   case _sl_batch:
             Poly->BatchParm((int)fl_get_slider_value(ob));		
	     break;
		
	   default:
	     break; 	
	  }
}

void t_homeo_demo::Load(char *to_parse)
{
	// put your loading stuff here and 
	int i,j;
	double d;

	if (sscanf(to_parse,"poly.C[%d,%d]=%lf",&j,&i,&d) == 3)
	   {
	    if ((i < n_sensors) && (j < MAX_POLY_PARMS))
	       {
		Poly->SetVal(j,i,d);
	        Poly->UseVal(j,i,true);
	       }

	    return;
	   }

	// if we come here that wasn't private stuff 
	// try the generic parser from parent object      
	t_runtime_object::Load(to_parse);

	robot_netspeed = fl_get_slider_value(fd_demo->slider[_sl_speed]);
}

void t_homeo_demo::Save(int fd)
{
	t_runtime_object::Save(fd);	// call parent for generic savings

	fprintf(stderr,"t_homeo_demo::Save()\n");

	// then save our private stuff
	char st[256];
	
	for (int j=0; j<MAX_POLY_PARMS; j++)
	  for (int i=0; i<n_sensors; i++)
	    {
	     if (Poly->C_used(j,i) == true)
	        {
		 sprintf(st,"poly.C[%d,%d]=%g\n",j,i,Poly->C_Val(j,i));
	         write(fd,st,strlen(st)); 	   
	        }
	    }
}

void t_homeo_demo::make_logstring(void)
{
	char st[4096], s2[256];

	for (int j=0; j<MAX_POLY_PARMS; j++)
          {
	   for (int i=0; i<n_sensors; i++)
	     {
	      if (Poly->C_used(j,i) == false)
	         continue;

	      double log = leftside(i)*Poly->C_logV(j,i);
	      sprintf(s2,"%g\t",log); 
	      strcat(st,s2);
	     }
	  }	 

	sprintf(Logs.data,"%s\n",st);
}

/*
void t_homeo_demo::make_logstring(void)
{
}
*/

char t_homeo_demo::calculate_module(char allow_learn, char any_new)
{
	if (any_new == false)
	   return false;

	if (t_runtime_object::calculate_module(allow_learn,any_new) == false)
	   return false;
	
	if (fl_get_button(fd_demo->cbox[_bt_wakeup]))
	   {
	    double max = Robot->Ired->Range.max;

	    if (max > 0.6)
               online = true;

	    if (max < 0.01)
	       {
		free_steps++;
		if (free_steps > (int)(50.0/(robot_netspeed + 0.1)))
		   online = false;
	       }
             else
	       free_steps = 0; 

 	    if (was_online != online)
 	       {
 		was_online = online;
    // 	    fprintf(stderr,"online: %d\a\n",online);
 	       }		

//	    if (online == false)
//	       return false;
	   }
         else
	   online = true; 


	double L = fl_get_slider_value(fd_demo->slider[_sl_learn]);
	int ph = (int)ceil(CrashTest_Demo.Phase.AvgV);
	double v_radius = g_radius.Get(ph);		

	double s = sinus.Get(ph) - Sin2.Get(ph);

	double ew = exp(-v_radius);
	double div = (1.0 + ew);
	div *= div;
	double g_ = 4.0 * ew / div;
	
	char wake = (online == false) && fl_get_button(fd_demo->cbox[_bt_wakeup]);

	int H = (int)ceil(fl_get_slider_value(fd_demo->slider[_sl_horiz]));

	double E = 0.0;
	double dxk[8];

	for (int i=0; i<8; i++)
	  {
           dxk[i] = Sensor[i].Get(0) - Sensor[i].Get(H);

	   q[i].Add(dxk[i]*s);

//	   double q = Sensor[i].Get(0) + Sensor[i].Get(2) - (2 * Sensor[i].Get(1)); 
//           q *= q;

	   E += (q[i].AvgV * dxk[i]);
	  }

	double X[n_sensors];
	for (int i=0; i<n_sensors; i++)
	  X[i] = Sensor[i].Get(1);

	double damp = fl_get_slider_value(fd_demo->slider[_sl_damp]);

	Poly->Grad(X, 0.01 , L     *    g_ * E , 
                             L * damp * g_ * E , wake);

	return true;
}


char t_homeo_demo::control_module(void)
{
	if (t_runtime_object::control_module() == false)
	   return false;

	Robot->MsgQueue.request_proximity();

	if (uselight == true)
	   Robot->MsgQueue.request_ambient();
//	Robot->MsgQueue.request_motorspeed();

	double tS[n_sensors];

	for (int i=0; i<8; i++)
	  {
	   tS[i] = Robot->Ired->Sensor[i]->Value;	
//	   fprintf(stderr,"%g\t",tS[i]);
	   Sensor[i].Add(tS[i]);	// Schieberegister 
	   
	   if (uselight == true)
              {
	       int j = i+8;
	       tS[j] = 	Robot->Ambl->Sensor[i]->AvgV; //Value;
	       Sensor[j].Add(tS[j]);
	      }
          }

//	tSensor[0][16] = (double)Robot->speed_left;
//	tSensor[0][17] = (double)Robot->speed_right;

//	place your control instructions after this comment line
//	fprintf (stderr,"%g %g %g %g\n",tSensor[0][0],tSensor[0][1],tSensor[0][2],tSensor[0][3]);

	double radius = Poly->Result(tS);
//	g_radius = radius;

	double r = ((2.0/(1.0+exp(-radius))) - 1.0) * fl_get_slider_value(fd_demo->slider[_sl_ampl]);
	g_radius.Add(r);

	double T = fl_get_slider_value(fd_demo->slider[_sl_freq]);
	double t = (double)step;
	double freq = 1.0 / T;
	double omega = 2.0 * M_PI * freq;
	double ot = omega *t;
	double s = sin(ot);

	sinus.Add(s);
	Sin2.Add(2*sin(ot * 2.0));

	s *= (fl_get_slider_value(fd_demo->slider[_sl_sinamp]) * omega); 

        if (fl_get_button(fd_demo->cbox[_bt_disturb]))
	   r += s;

        double rns = r * robot_netspeed;                                                        
                                                                                                
//      fprintf(stderr,"%g, %d\n",robot_netspeed);                                              
//      rns *= ns_direction;                                                                    
                                                                                                
        double vr,vl;                                                                           
        vr = robot_netspeed + rns;                                                              
        vl = robot_netspeed - rns;                                                              
                                                                                                
        step++;                                                                                 



        Robot->SetMotorSpeed(vl,vr);                                                            
                                                                                                
        return true;                                                                            
}                                                                                               
                                                                                                
                                                                                                
                                                                                                
                                                                                                
                                                                                                
char t_homeo_demo::start_module(void)                                                           
{                                                                                               
        if (t_runtime_object::start_module() == false)                                          
           return false;                                                                        
                                                                                                
//      place after that                                                                        
        fprintf(stderr,"t_homeo_demo::start_module()\n");                                       
        step = 0;                                                                               
        online = true;                                                                          
                                                                                                
        if (fl_get_button(fd_demo->cbox[_bt_random]))                                           
           {                                                                                    
            for (int i=0; i<16; i++)                                                            
              for (int j=0; j<MAX_POLY_PARMS; j++)                                              
                 Poly->SetVal(j,i,(2.0*random_uniform())-1.0);                                  
                                                                                                
                                                                                                
//            Poly->SetVal(0,2,-2.8);                                                           
                                                                                                
//            Poly->SetVal(0,3,-2.8);                                                           
                                                                                                
           }                                                                                    
        return true;                                                                            
}                                                                                               
                                                                                                
                                                                                                
char t_homeo_demo::stop_module(void)                                                            
{                                                                                               
        if (t_runtime_object::stop_module() == false)                                           
           return false;                                                                        
                                                                                                
//      place after that                                                                        
        fprintf(stderr,"t_homeo_demo::stop_module()\n");                                        
                                                                                                
        return true;                                                                            
}                                                                                               
                                                                                                
                                                                                                
void t_homeo_demo::Reset(void)                                                                  
{                                                                                               
        for (int j=0; j<6; j++)                                                                 
          for (int i=0; i<16; i++)                                                              
            Poly->SetVal(j,i,0.0);                                                              
                                                                                                
        // do some Resetting                                                                    
        t_runtime_object::Reset();                                                              
}                                                                                               
                                                                                                
                                                                                                 
void t_homeo_demo::Done(void)                                                                   
{                                                                                               
        t_runtime_object::Done();                                                               
                                                                                                
        for (int i=0; i<n_sensors; i++)                                                         
           Sensor[i].Done();                                                                    
                                                                                                
        sinus.Done();                                                                           
        g_radius.Done();                                                                        
        Sin2.Done();                                                                            
                                                                                                
        Poly->Done();                                                                           
        delete Poly;                                                                            
}                                                                                               
                                                                                                
                                                                                                
                                                                                                
                                                                                                


/*
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>


#include "t_runtime_obj.h"

#include "stuff.h"


void t_runtime_root::Init(void)
{
	state = _s_undefined;

	for (int i=0; i<MAX_RUNTIME_OBJS; i++)
	  RunObj[i] = NULL;

	number = 0;
}


void t_runtime_root::Add(t_runtime_object *o)
{
	if (number >= MAX_RUNTIME_OBJS)
	   return;	// don't exceed defined buffer

	if (o == NULL)
	   return;	// don't add wrong objects

	for (int i=0; i<number; i++)
	   if (RunObj[i] == o)
	      return;	// don't add already existing objects

	RunObj[number] = o;
	RunObj[number]->id = number;
	number++;
}



void t_runtime_root::Remove(t_runtime_object *o)
{
	if (number <= 0)
	   return;

	int i;
	for (i=0; i<number; i++)
	  {
           if (RunObj[i] == o)
	      break;
	  }

	if (i == number)
	   return;		// nothing to delete	

	number--;
	RunObj[i] = RunObj[number];	// swap last to this position
	RunObj[number] = NULL;
}

void t_runtime_root::Done(void)
{
//	fprintf(stderr,"t_runtime_root::Done()\n");
	stop();

	for (int i=0; i<number; i++)
	  {
	   if (RunObj[i] != NULL)
	      RunObj[i]->Done();
	  }	
}

void t_runtime_root::do_slider(FL_OBJECT *ob, long data)
{
	int prefix = data / 1000;
	int action = data % 1000;
	
	if (prefix >= number)
	   return;
	
	RunObj[prefix]->slider_cb(ob,action);
}

void t_runtime_root::do_button(FL_OBJECT *ob, long data)
{
	int prefix = data / 1000;
	int action = data % 1000;

	if (prefix >= number)
	   return;

	RunObj[prefix]->button_cb(ob,action);
}

void t_runtime_root::calculate(char allow_learn, char any_new)
{
	if (number < 1)
	   return;
	
	for (int i=0; i<number; i++)
	  {
	   if (RunObj[i] != NULL)
	      {
	       if (RunObj[i]->niced == false)
	   	  RunObj[i]->calculate_module(allow_learn, any_new);
              }
          }

	state = _s_running;
}

void t_runtime_root::control(void)
{
	if (number < 1)
	   return;
	
	for (int i=0; i<number; i++)
	  {
	   if (RunObj[i] != NULL)
	      {
	       if (RunObj[i]->paused == false)
		  RunObj[i]->control_module();
	      }
	  }	

	state = _s_running;
}

void t_runtime_root::start(void)
{
//	fprintf(stderr,"t_runtime_root::start() number=%d\n",number);

	if (number < 1)
	   return;
	
	for (int i=0; i<number; i++)
	  {
	   if (RunObj[i] != NULL)
	       if ((RunObj[i]->paused != true) || (RunObj[i]->niced != true))
                   RunObj[i]->start_module();
	  }	

	state = _s_started;
}

void t_runtime_root::stop(void)
{
	if (number < 1)
	   return;
	
	for (int i=0; i<number; i++)
	  {
//	   fprintf(stderr,"root::stop(%d)\n",i);
	   if (RunObj[i] != NULL)
              RunObj[i]->stop_module();
	  }	

//	Robot_.MsgQueue.send_motorspeed(0,0);

	t_robot_basic *r = (t_robot_basic *)&Robot_;

	int L,R;
	L = 0; R = 0;
	r->SetMotorSpeed(L,R);
	state = _s_cleared;
}

void t_runtime_root::pause(char pp)
{
	if (number < 1)
	   return;
	
	for (int i=0; i<number; i++)
	  {
//	   fprintf(stderr,"root::stop(%d)\n",i);
	   if (RunObj[i] != NULL)
              RunObj[i]->pause_module(pp);
	  }	

//	Robot_.MsgQueue.send_motorspeed(0,0);
	if (pp == true)
	   {
	    t_robot_basic *r = (t_robot_basic *)&Robot_;
	    int L,R;
	    L = 0; R = 0;
	    r->SetMotorSpeed(L,R);

	    if (state == _s_running)
		state = _s_paused;

	    return;
	   } 

	if (state == _s_paused)
	   state = _s_running;
}


void t_runtime_root::Execute_Cntl(char Do, char pp)
{
//	fprintf(stderr,"t_runtime_root::Execute_Cntl() state=%d\n",state);

	switch (state)
	  {
	   case _s_halted:
//	     if (Do == true)
	     stop();
	     break;

	   case _s_cleared:
	   case _s_undefined:
	     if (Do == true)
 	         start();
	     break;

	   case _s_started:
	   case _s_running:
	     if ((pp == true) && (state == _s_running))	
		{
	         pause(pp);
		 return;
	        }
	      
	     if ((pause == false) && (state == _s_paused))
	        {
		 pause(pp);
	         return;
		}
 
             if (Do == true)
	         control();
              else
		 state = _s_halted;
             break;
	  }
}


void t_runtime_root::Execute_Calc(char Do, char allow_learn, char any_new)
{
//	fprintf(stderr,"t_runtime_root::Execute_Calc() state=%d, this=0x%08lx\n",state,(long)this);

	switch (state)
	  {
	   case _s_halted:
	     if (Do == true)
		 stop();

	   case _s_cleared:
	   case _s_undefined:
	     if (Do == true)
		 start();
	     break;

	   case _s_started:
	   case _s_running:	
             if (Do == true)
		 calculate(allow_learn, any_new);
              else
		 state = _s_halted;
             break;
	  }
}

void t_runtime_root::Show(void)
{
//	fprintf(stderr,"t_runtime_root::Show() state=%d, this=0x%08lx\n",state,(long)this);

	if (number < 1)
	   return;
	
	for (int i=0; i<number; i++)
	  {
	   if (RunObj[i] != NULL)
	      if (RunObj[i]->visible == true)
                 RunObj[i]->Show();
	  }	
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


char dummyboxes[3][8] = {"erste\0","zweite\0","dritte\0"};
char dummysliders[2][16] = {"uno\0","dos\0"};

void t_runtime_object::Init(char *name, RobotContext *robot)
{
	char *cb_pointers[] = {&dummyboxes[0][0],&dummyboxes[1][0],&dummyboxes[2][0]};
	char *sl_pointers[] = {&dummysliders[0][0],&dummysliders[1][0]};
 
	Init(name,robot,0,2,3,sl_pointers,cb_pointers);
}

void t_runtime_object::Init(char *name, RobotContext *robot,
				int ps,int nsld,int nbox,char **sldn,char **boxn)
{
	if (name != NULL)
	    strcpy(Name,name);

//	fprintf(stderr,"t_runtime_object::Init(%s)\n",Name);

	cntl_age = 0;
	calc_age = 0;
	paused = true;
	niced = true;
	Robot = robot;
	state = _s_undefined;
	visible = false;
	props = ps;

	nsliders = nsld;
	ncboxes = nbox;
	BoxName = boxn;
	SliderName = sldn; 

	Logs.wival = 0;
	Logs.average = 0.0;
	strcpy(Logs.data,"\0");
	Logs.step = 0;

	fd_demo = create_form_demo(Name,id,nsliders,ncboxes,SliderName,BoxName);
//	sl_prec = new int[nsliders];

//	for (int i=0; i<nsliders; i++)
//          sl_prec[i] = 2;
}


void t_runtime_object::Done(void)
{
	fprintf(stderr,"t_runtime_object::Done(%s)\n",Name);
	stop_module();
	done_form_demo(fd_demo);
//	delete sl_prec;
}


char object_str[] = "native t_runtime_object::";

void t_runtime_object::Show(void)
{
	     fprintf(stderr,"%sShow() called but not overloaded\n",object_str);
}

void t_runtime_object::Save(int fd)
{
	double low,high,value;
	int on;

	fprintf(stderr,"%sSave()\n",object_str);

	char st[256];
	for (int i=0; i<nsliders; i++)
	  {
	   fl_get_slider_bounds(fd_demo->slider[i],&low,&high);
	   value = fl_get_slider_value(fd_demo->slider[i]);
	   
	   char *S = (char *)fd_demo->slider[i]->spec;
#ifndef Linux
	   int prec =  S[15];
#else
	   int prec =  S[12];
#endif
		//fl_get_slider_precision(fd_demo->slider[i]);

	   for (int j=0; j<32; j++)
             fprintf(stderr,"%d,",S[j]); 

	   fprintf(stderr,"\n");

	   sprintf(st,"slider[%d].Label=\"%s\"\n",
		    i,fd_demo->slider[i]->label);
	   write(fd,st,strlen(st));
	   sprintf(st,"slider[%d].top=%g\n",i,high);
	   write(fd,st,strlen(st));
	   sprintf(st,"slider[%d].bottom=%g\n",i,low);
	   write(fd,st,strlen(st));
	   sprintf(st,"slider[%d].value=%g\n",i,value);
	   write(fd,st,strlen(st));

	   sprintf(st,"slider[%d].prec=%d\n",i,prec);
	   write(fd,st,strlen(st));
	  }	

	for (int i=0; i<(ncboxes+_bt_num); i++)
	  {
	   sprintf(st,"box[%d].on=%d\n",i,fl_get_button(fd_demo->cbox[i]));
	   write(fd,st,strlen(st));
	  }	
}

void t_runtime_object::Load(char *to_parse)
{
	double d,low,high;
	int i,j;

	if (sscanf(to_parse,"slider[%d].top=%lf",&i,&d) == 2)
	   {
	    if (i >= nsliders)
	       return;
	       
	    fl_get_slider_bounds(fd_demo->slider[i],&low,&high);
	    fl_set_slider_bounds(fd_demo->slider[i],low,d);
           }

	if (sscanf(to_parse,"slider[%d].bottom=%lf",&i,&d) == 2)
	   {
	    if (i >= nsliders)
	       return;
	       
	    fl_get_slider_bounds(fd_demo->slider[i],&low,&high);
	    fl_set_slider_bounds(fd_demo->slider[i],d,high);
           }
	    
	if (sscanf(to_parse,"slider[%d].value=%lf",&i,&d) == 2)
	   {
	    if (i >= nsliders)
	       return;
	       
	    fl_set_slider_value(fd_demo->slider[i],d);
           }

	if (sscanf(to_parse,"slider[                 
{                                                                                               
        for (int j=0; j<6; j++)                                                                 
          for (in


*/







/**/
/**/
/**/
/**/
/**/
/**/
/**/
/**/
/*****  End Of File  ****************************/
