/* 
 * Thomas Pantzer: kalah_cb.cc, v0.1b  27.1.98 22:12 
 * 
 * 
 * Copyright 1998 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@aix520.informatik.uni-leipzig.de   (Thomas Pantzer) 
 * 
 */


#include "forms.h"
#include "kalah.h"
#include "string.h"
#include "stuff.h"
#include "utils.h"
#include "netutils.h"
#include "copyright.h"

#include <unistd.h>

/* callbacks for form kalah */


#define SendMsg(x,y)	write(x,y,8);

int start;

int check_players_kalah(int start)
{
  if ((start > 0) && (start < 7))
     return 7;
  
  return 0;
}


void switch_cb(void)
{
   if (fl_get_button(fd_kalah->move_bt[0]) == 1)
      {
       fl_set_button(fd_kalah->move_bt[0],0);
       fl_set_button(fd_kalah->move_bt[1],1);
       
       for (int i=0; i<6; i++)
         {
          fl_deactivate_object(fd_kalah->holder[8+i]);

          if (peer == 0)
             fl_activate_object(fd_kalah->holder[1+i]);
         }
      } 
    else  
      {
       fl_set_button(fd_kalah->move_bt[0],1);
       fl_set_button(fd_kalah->move_bt[1],0);
       
       for (int i=0; i<6; i++)
         {
          fl_deactivate_object(fd_kalah->holder[1+i]);
          fl_activate_object(fd_kalah->holder[8+i]);
         }
      } 
}


int get_beans(FL_OBJECT *ob)
{
  int r;
  char st[256];
  
  strcpy(st,ob->label);
  
  if (sscanf(st,"%d",&r) == 1)
     return r;
     
  return 0;
}

int empty_cb(FL_OBJECT *ob)
{
  int num = get_beans(ob);
  char st[256] = "0";
  fl_set_object_label(ob,st);
  
  return num;
}

void add_point(FL_OBJECT *ob)
{
   int n;
   char st[256];
   
   n = get_beans(ob);
   sprintf(st,"%d",n+1);
   fl_set_object_label(ob,st);
}


void move_cb(int id, int num)
{
   if (num == 0)
       return;
      
   if (num == 1)
      { // last bean
       if (id == check_players_kalah(start)) 
          switch_cb();  // bonus, get game control back (get next move)
         
       if ((get_beans(fd_kalah->holder[id]) == 0) && (id != 0) && (id != 7))
          {
           if (check_players_kalah(id) == check_players_kalah(start))
              {
               int k = empty_cb(fd_kalah->holder[14 - id]); // get competants beans
               
               if (k > 0)
                  {               
                   id = check_players_kalah(id);  
    
                   for (int i=0; i<k; i++)
                     add_point(fd_kalah->holder[id]);   
                  }   
              }   
          }   
      }   
      
   add_point(fd_kalah->holder[id]);   

   int n = (id +1) % 14;
   
   move_cb(n,num-1);
}


void reset_game(void)
{
  for (int i=0; i<14; i++)
    {
     if ((i == 0) || (i == 7))
        empty_cb(fd_kalah->holder[i]);
      else
        fl_set_object_label(fd_kalah->holder[i],"6");
    } 
    
    
  if (ssock != 0)
     {  
      if (fl_get_button(fd_kalah->move_bt[1]) == 1)
         switch_cb();
     }    
   else      
     {  
      if (fl_get_button(fd_kalah->move_bt[0]) == 1)
         switch_cb();
     }    
}



void player_cb(int data)
{
  // empty me
  int num = empty_cb(fd_kalah->holder[data]);

  if (num == 0)
     return;
  
  start = data;

  // return game control to competant 
  switch_cb();
 
  // stray the beans recursive 
  int n = (data +1) % 14;
  move_cb(n,num);
}


void button_cb(FL_OBJECT *ob, long data)
{
  /* fill-in code for callback */
  switch (data)
    {
     case -1:
       if (peer != 0)
          {
           SendMsg(peer,"exit 1  ");
           ShutDown(peer);
          }
          
       exit(0);
       break;

     case -2:  
       reset_game();

       if (peer != 0)
          SendMsg(peer,"reset 1 ");   
       return;
       break;
       
     case -3:
     case -4:
       switch_cb();       
       return;
       break;  
    }    

  player_cb((int)data);
  
  if (peer != 0)
     {
      char st[32];
      sprintf(st,"move %d  ",start-7);
      SendMsg(peer,st);
     } 
}



int idle_cb(XEvent *xev, void *d)
{
   if (peer == 0)
      return 0; 

   if (FD_Ready(peer) == true)
      {
        char msg[64];
        int i;
        int r = read(peer,&msg[0],8);
 
        if (sscanf(msg,"reset %d",&i) == 1)
           {
            reset_game();
            return 0;
           } 

        if (sscanf(msg,"exit %d",&i) == 1)
           {
            ShutDown(peer);
            exit(0);
           } 
         
        if (sscanf(msg,"move %d",&i) == 1)
           {
            player_cb(i);
           } 
      }
      
   return 0;    
}


