
// Positions.java
// Andrew Davison, April 2005, ad@fivedots.coe.psu.ac.th

/*
 *	@(#)Positions.java 1.11 01/01/11 07:32:12
 * Copyright (c) 1996-2001 Sun Microsystems, Inc. All Rights Reserved

   Třída Positions vytváří kuličky a krychličky označující tahy hráčů.
   Zpočátkou jsou na všech pozicích malé bílé kuličky, ale tyto jsou
   při klepnutí na danou pozici hráčem nahrazeny červenými kuličkami 
   nebo modrými krychličkami.

   Hráče 1 reprezentují červené kuličky.
   Hráče 2 reprezentují modré kostičky.
 */

import javax.media.j3d.*;
import javax.vecmath.*;
import java.util.BitSet;
import com.sun.j3d.utils.geometry.*;



public class Positions 
{
   private final static int NUM_SPOTS = 64;    // na herní desce (4*4*4)
   private final static int PLAYER1 = 1;
   private final static int PLAYER2 = 2;   // dříve šlo o počítač (MACHINE)

   private Switch posSwitch, player1Switch, player2Switch;
   private BitSet posMask, player1Mask, player2Mask;

   private Appearance blueApp, redApp, whiteApp;

   private Vector3f[] points;
   private Group group;


   public Positions() 
   {
      initAppearances();
      initLocations();

      group = new Group(); 
      // vytvoř nejrůznější značky a přidej je do skupiny
      makeWhiteSpheres();
      makeRedSpheres();
      makeBlueCubes();
   } // konec metody: Positions()


   private void initAppearances()
   // vytvoří bílí, červený a modrý materiál
   {
      // define colors
      Color3f white     = new Color3f(1.0f, 1.0f, 1.0f);
      Color3f black     = new Color3f(0.0f, 0.0f, 0.0f);
      Color3f red       = new Color3f(0.9f, 0.1f, 0.2f);
      Color3f blue      = new Color3f(0.3f, 0.3f, 0.8f);
      Color3f ambRed    = new Color3f(0.3f, 0.03f, 0.03f);
      Color3f ambBlue   = new Color3f(0.03f, 0.03f, 0.3f);
      Color3f ambWhite  = new Color3f(0.3f, 0.3f, 0.3f);
      Color3f specular  = new Color3f(1.0f, 1.0f, 1.0f);

      // Vytvoř uzel pro červený vzhled
      // Create the red appearance node
      Material redMat= new Material(ambRed, black, red, specular, 100.f);
      redMat.setLightingEnable(true);
      redApp = new Appearance();
      redApp.setMaterial(redMat);

      // Vytvoř uzel pro modrý vzhled
      Material blueMat= new Material(ambBlue, black, blue, specular, 100.f);
      blueMat.setLightingEnable(true);
      blueApp = new Appearance();
      blueApp.setMaterial(blueMat);

      // Vytvoř uzel pro bílí vzhled
      Material whiteMat= new Material(ambWhite, black, white, specular, 100.f);
      whiteMat.setLightingEnable(true);
      whiteApp = new Appearance();
      whiteApp.setMaterial(whiteMat);
   }  // konec metody: initAppearances()


   private void initLocations()
   /* Načte pole bodů s posuny (souřadnicemi) pro každou pozici od 0 do NUM_SPOTS. */
   {
      points = new Vector3f[NUM_SPOTS];
      int count = 0;
      for (int z=-30; z<40; z+=20) {
         for (int y=-30; y<40; y+=20) {
            for (int x=-30; x<40; x+=20) {
               points[count] = new Vector3f((float)x, (float)y, (float)z);
               count++;
            }
         }
      }
   }  // konec metody: initLocations()



   private void makeWhiteSpheres()
   /* Vytvoří malou bílou kuličku, která označuje dosud neoznačená pole.
      Umístí je pod přepínač pomocí bitsetu, který umožní jejich zapínání/vypínání.
   */
   {
      // Vytvoř uzly typu Switch
      posSwitch = new Switch(Switch.CHILD_MASK);
      // Nastav bity oprávnění přístupu
      posSwitch.setCapability(Switch.ALLOW_SWITCH_READ);
      posSwitch.setCapability(Switch.ALLOW_SWITCH_WRITE);
      posMask = new BitSet();   // vytvoři bitovou masku

      Sphere posSphere;
      for (int i=0; i<NUM_SPOTS; i++) {
         Transform3D t3d = new Transform3D();
         t3d.set( points[i] );    // nastav pozici
         TransformGroup tg = new TransformGroup(t3d);
         posSphere = new Sphere(2.0f, whiteApp);
         Shape3D shape = posSphere.getShape(); 
         shape.setUserData( new Integer(i) ); // ke každému tvaru přidej ID pozice na herní desce
         tg.addChild( posSphere );
         posSwitch.addChild(tg);
         posMask.set(i);    // zviditelni
      }
      // Nastav masku pro pozice
      posSwitch.setChildMask(posMask);

      group.addChild( posSwitch );
   } // konec metody: makeWhiteSpheres()


   private void makeRedSpheres()
   // Vytvoří červené kuličky, které označují pozici uživatele.
   // Umístí je je pod přepínač pomocí bitsetu, který umožní jejich zapínání/vypínání.
   {
      // Vytvoř uzly typu Switch
      player1Switch = new Switch(Switch.CHILD_MASK);
      // Nastav bity oprávnění přístupu
      player1Switch.setCapability(Switch.ALLOW_SWITCH_READ);
      player1Switch.setCapability(Switch.ALLOW_SWITCH_WRITE);
      player1Mask = new BitSet();   // vytvoři bitovou masku

      for (int i=0; i<NUM_SPOTS; i++) {
         Transform3D t3d = new Transform3D();
         t3d.set( points[i] );    // nastav pozici
         TransformGroup tg = new TransformGroup(t3d);
         tg.addChild(new Sphere(7.0f, redApp));
         player1Switch.addChild(tg);
         player1Mask.clear(i);   // zneviditelni
      }
      // Nastav masku pro pozice
      player1Switch.setChildMask(player1Mask);

      group.addChild( player1Switch );
   }  // konec metody: makeRedSpheres()


   private void makeBlueCubes()
   // Vytvoří modré kostičky označující pozice počítače.
   // Umístí je pod přepínač pomocí bitsetu, který umožní jejich zapínání/vypínání.
   {
      // Vytvoř uzly typu Switch
      player2Switch = new Switch(Switch.CHILD_MASK);
      // Nastav bity oprávnění přístupu
      player2Switch.setCapability(Switch.ALLOW_SWITCH_READ);
      player2Switch.setCapability(Switch.ALLOW_SWITCH_WRITE);
      player2Mask = new BitSet();   // vytvoři bitovou masku

      for (int i=0; i<NUM_SPOTS; i++) {
         Transform3D t3d = new Transform3D();
         t3d.set( points[i] );    // nastav pozici
         TransformGroup tg = new TransformGroup(t3d);
         tg.addChild( new Box(5.0f, 5.0f, 5.0f, blueApp) );
         player2Switch.addChild(tg);
         player2Mask.clear(i);   // zneviditelni
      }
      // Nastav masku pro pozice
      player2Switch.setChildMask(player2Mask);

      group.addChild( player2Switch );
   }  // konec metody: makeBlueCubes()


   public Group getChild() 
   { return group; }



  public void set(int pos, int player) 
  // volá se ze třídy Board pro aktualizaci 3D-scény
  {
    // System.out.println("Hráč " + player + " klepnul na pozici " + pos);
    // vypni bílou značku zvolené pozice
    posMask.clear(pos);
    posSwitch.setChildMask(posMask);

    // zapni jednu ze značek hráče
    if (player == PLAYER1) {
       player1Mask.set(pos);
       player1Switch.setChildMask(player1Mask);   // červená kulička pro hráča1
    }
    else if (player == PLAYER2) {   
       player2Mask.set(pos);
       player2Switch.setChildMask(player2Mask);   // modrá kostička pro hráče2
    }
    else 
       System.out.println("Neplatná hodnota hráče: " + player);
  } // konec metody: set()


} // konec třídy: Positions
