/*******************************************************************/
//              "Меркурий"-"Правда" - open source переводчик
//          распространяется в соответсвии с лицензией GNU v 2.0
//
//                             менюшка
//     Анисимов Д.В.                               сегодня
/*******************************************************************/

# include <stdio.h>
# include <malloc.h>
# include <string.h>

# include "mylib.h"
# include "video.h"
# include "color.h"
# include "menu.h1"

# define stop() {  short key1,key2 ; s_getch(&key1,&key2); }
 
/* ----------------------------------------------------------------------- */

struct t_menuForm
{  short   size_x,size_y,
	   n_punkt,
	  *igrek ;
   t_Menu *menu ;
} ;

static   char   *stek ;
static   short   SP ;
static   short  *mass_iks, *mass_igrek, Ret ;
static   char    Exist=0 ;

/* ----------------------------------------------------------------------- */

void   init_menu( void ) ;
short  hor_menu( short y, t_Menu *menu ) ;
void   s_hor_menu( short y, short *x, t_Menu *menu, short pos=-1 ) ;
void   s_ver_menu( short y, short x, t_menuForm F, short pos=-1 ) ;
short  ver_menu( short y, short x, t_Menu *menu ) ;
void   ver_menu_creat( t_menuForm *f, t_Menu *menu ) ;
short  sehen_hor_menu( short **x, t_Menu *menu ) ;
static short  schnell_taste( t_Menu *menu, uchar taste ) ;
void   sorry( short y, short x );

/* *********************************************************************** */
short menu( void )
{
    Ret=0 ;
    if( Exist==0 ) init_menu( );
    hor_menu( 0, wort_menu ) ;
    null_menu( );
    SP=0 ;
    return Ret ;
}
/* ----------------------------------------------------------------------- */
void init_menu( void )
{
    stek       = (char  *)Calloc( 4000,1 ) ;
    mass_iks   = (short *)Calloc( 25,sizeof(short) ) ;
    mass_igrek = (short *)Calloc( 25,sizeof(short) ) ;
    SP=0 ;
    Exist=1 ;
}
/* ----------------------------------------------------------------------- */
void null_menu( void )
{  short *x ;

   if( Exist==0 ) init_menu( );
   sehen_hor_menu( &x,wort_menu ) ;
   s_hor_menu( 0,x,wort_menu ) ;
}
/* ----------------------------------------------------------------------- */
/*             реакция на кнопки внутри горизонтального меню               */
/* ----------------------------------------------------------------------- */
short hor_menu( short y, t_Menu *menu )
{  short p=0,        // текущий пункт меню
	 flag=0 ;
   static short key1,key2,key3 ;
   short size_Menu ;
   short *x ;

   size_Menu=sehen_hor_menu( &x,menu ) ;
   while( 1 )
   {
       s_hor_menu( y,x,menu,p ) ;

       s_getch( &key1,&key2) ;

       switch( key2 )
       {   case S_key_Left: M_LINKS :
		if( p<=0 ) p=size_Menu-1 ; else p-- ;
		if( flag==1 && menu[p].flag==F_MENU )
		{   s_hor_menu( y,x,menu,p );
		    key3=ver_menu( 1,x[p], (t_Menu *)menu[p].data ) ;
		}
		else
		{  key3=0 ; }
		break ;
	   case S_key_Right: M_RECHTS :
		if( p>=size_Menu-1 ) p=0 ; else p++ ;
		if( flag==1 && menu[p].flag==F_MENU )
		{   s_hor_menu( y,x,menu,p );
		    key3=ver_menu( 1,x[p], (t_Menu *)menu[p].data ) ;
		}
		else
		{  key3=0 ; }
		break ;
	   case S_key_Down: goto M_ENTER ;
	   case S_key_F10 : return S_key_Esc ;
	   case 0 :
	   switch( key1 )
	   {
		schnell :
		    s_hor_menu( y,x,menu,p );
		case '\r' : M_ENTER :
		   if( menu[p].flag==4 )
		   {   Ret=((char *)menu[p].data)[0] ;
		       return S_key_Esc ;
		   }
		   if( menu[p].flag==3 )
		   {   menu[p].funk( menu[p].data ) ;
		       return S_key_Esc ;
		   }
		   if( menu[p].flag==2 )
		   {   flag=1 ;
		       key3=ver_menu( 1,x[p], (t_Menu *)menu[p].data ) ;
		   }
		   break ;
	       case S_key_Esc : return S_key_Esc ;
	       default :
		   {   short p1 ;
		       p1=schnell_taste( menu,key1 ) ;
		       if( 0<=p1 ) {  p=p1 ; goto schnell ;  }
		   }
		   break ;
	   }
       }
       switch( key3 )
       {   case S_key_Left : goto M_LINKS ;
	   case S_key_Right: goto M_RECHTS ;
	   case S_key_Esc  : return S_key_Esc ;
       }
   }
}
/* ----------------------------------------------------------------------- */
/*              реакция на кнопки внутри вертикального меню                */
/* ----------------------------------------------------------------------- */
short ver_menu( short y, short x, t_Menu *menu )
{  short p=0,ret ;
   static short key1,key2 ;
   t_menuForm  f ;
   short i ;

   ver_menu_creat( &f,menu ) ;
   s_save( y,x,y+f.size_y+1,x+f.size_x+1 );
   while( 1 )
   {
       s_ver_menu( y,x,f,p ) ;

       s_getch( &key1,&key2 ) ;

       switch( key2 )
       {   case S_key_Up:
		if( p<=0 ) p=f.n_punkt-1 ; else p-- ; break ;
	   case S_key_Down:
		if( p>=f.n_punkt-1 ) p=0 ; else p++ ; break ;
	   case S_key_Left : ret = S_key_Left ;  goto ENDE ;
	   case S_key_Right: ret = S_key_Right ; goto ENDE ;
	   case S_key_F10  : ret = S_key_Esc ;   goto ENDE ;
	   case 0 :
	       switch( key1 )
	       {   case '\r' :
	   schnell :   i=f.igrek[p] ;
		       if( menu[i].flag==4 )
		       {   Ret=((char *)menu[p].data)[0] ;
			   ret = S_key_Esc ;
			   goto ENDE ;
		       }
		       if( menu[i].flag==3 )
		       {   s_restore( ) ;
			   menu[i].funk( menu[i].data ) ;
			   ret = S_key_Esc ;  goto ENDE1 ;
		       }
		       if( menu[i].flag==2 )
		       {   ver_menu( y+i+1,x+f.size_x, (t_Menu *)menu[p].data ) ;
			   break ;
		       }
		   default :
		       {   short p1 ;
			   p1=schnell_taste( menu,key1 ) ;
			   if( 0<=p1 ) {  p=p1 ; goto schnell ;  }
		       }   break ;
	       }
	   case S_key_Esc : ret = S_key_Esc ; goto ENDE ;
       }
   }
ENDE :  s_restore( ) ;
ENDE1 :
   return ret ;
}
/* ----------------------------------------------------------------------- */
short schnell_taste( t_Menu *menu, uchar taste )
{  short i,j ;
   uchar c ;

   for( i=0 ; menu[i].flag!=0 ; i++ )
   {   for( j=0 ; ; j++ )
       {   c=menu[i].name[j] ;
	   if( c==0 ) break ;
	   if( (uchar)'А'<=c && c<=(uchar)'Я' )
	   {   if( c==taste ) return i ;
	       //if( XLAT[c]==XLAT[taste] ) return i ;
	       break ;
	   }
       }
   }
   return -1 ;
}
/* ----------------------------------------------------------------------- */
short sehen_hor_menu( short **iks, t_Menu *menu )
{  short i,j, *a ;

   *iks=a = mass_iks ;
   for( j=2,i=0 ; ; i++ )
   {  if( menu[i].flag==0 ) break ;
      a[i]=j ;
      j+=strlen( menu[i].name )+2 ;
   }
   return i ;
}
/* ----------------------------------------------------------------------- */
/*                     изобразить горизонтальное меню                      */
/* ----------------------------------------------------------------------- */
void s_hor_menu( short y, short *x, t_Menu *menu, short pos )
{  short i ;

   s_text_yxf( y,0,h_menu_Color,emptystr(80) ) ;
   for( i=0 ; i<25 ; i++ )
   {  if( menu[i].flag==0 ) break ;
      s_text_yxf( y,x[i],h_menu_Color,menu[i].name ) ;
   }
   // ------- изобразить текущую позицию горизонтального меню -------
   if( 0<=pos )
       s_text_yxf( y,x[pos],h_curs_Color,menu[pos].name ) ;
}
/* ----------------------------------------------------------------------- */
/*                     изобразить вертикальное меню                        */
/* ----------------------------------------------------------------------- */
void s_ver_menu( short y, short x, t_menuForm F, short pos )
{  short i,c ;

   s_rame1_F( y,x,y+F.size_y+1,x+F.size_x+1,v_menu_Color ) ;
   for( i=0 ; i<F.size_y ; i++ )
   {  if( i==mass_igrek[pos] )
      {   s_text_yxf( y+1+i,x+1,v_curs_Color,emptystr(F.size_x) ) ;
	  c=v_curs_Color ;
      }
      else c=v_menu_Color ;
      s_text_yxf( y+1+i,x+1,c,F.menu[i].name ) ;
   }
}
/* ----------------------------------------------------------------------- */
/*                       конструктор формы меню                            */
/* ----------------------------------------------------------------------- */
void ver_menu_creat( t_menuForm *f, t_Menu *menu )
{  short i,j,s,*igrek ;

   for( i=0 ; i<25 ; i++ ) if( menu[i].flag==0 ) break ;
   f->size_y=i ;

   igrek = mass_igrek ;
   for( s=j=0,i=0 ; i<f->size_y ; i++ )
   {  if( menu[i].flag==0 ) break ;
      s=max( (unsigned)s, strlen( menu[i].name ) );
      if( menu[i].flag==2 || menu[i].flag==3 || menu[i].flag==4 )
	  igrek[j++]=i ;
   }
   f->size_x=s ;     f->n_punkt=j ;
   f->igrek=igrek ;  f->menu=menu ;
}
/* ----------------------------------------------------------------------- */
//            переобозвать пункт меню (поставить в него галку)
/* ----------------------------------------------------------------------- */
char menu_set( t_Menu *Menu, char *sFind, char *sReplace )
{  short i ;

   for( i=0 ; i<100 ; i++ )
   {  if( Menu[i].flag==F_ENDE ) break ;
      if( 0==strcmp(Menu[i].name,sFind) )
      {   strcpy( Menu[i].name,sReplace );
          return 1 ;
      }	  
      if( Menu[i].flag==F_MENU )
          if( 1==menu_set( (t_Menu *)Menu[i].data,sFind, sReplace ) ) return 1;
   }
   return 0 ;
}
/* ----------------------------------------------------------------------- */
void menu_set( char *sFind, char *sReplace )
{
   menu_set( wort_menu, sFind, sReplace );
}
/* ----------------------------------------------------------------------- */
//                    найти пункт меню по его имени
/* ----------------------------------------------------------------------- */
t_Menu * menu_find( t_Menu *Menu, char *sFind )
{  short i ;

   for( i=0 ; i<100 ; i++ )
   {  if( Menu[i].flag==F_ENDE ) break ;
      if( 0==strcmp(Menu[i].name,sFind) )
          return &Menu[i] ;
      if( Menu[i].flag==F_MENU )
          return menu_find( (t_Menu *)Menu[i].data,sFind );
   }
   return NULL ;
}
/* ----------------------------------------------------------------------- */
t_Menu * menu_find( char *sFind )
{
   return menu_find( wort_menu, sFind );
}
/* ----------------------------------------------------------------------- */
void Sorry( void *d ){   sorry( 10,30 ) ;  }
/* ----------------------------------------------------------------------- */
void sorry( short y, short x )
{
   s_save( y,x,y+4,x+20 ) ;
   s_rame1_f( y,x,y+4,x+20,0x70 ) ;
   s_text_yxf( y+1,x+1,0x70,"      Извините     ") ;
   s_text_yxf( y+2,x+1,0x70,"  эта функция еще  ") ;
   s_text_yxf( y+3,x+1,0x70,"  не  реализована  ") ;

   stop( ) ;
   s_restore( ) ;
}