
// CommandsPanel.java
// Thana Konglikhit, October 2003, s4310170@maliwan.psu.ac.th
// Andrew Davison, April 2005, ad@fivedots.coe.psu.ac.th

/* Třída CommandsPanel uchovává textové vstupní pole pro zadávání 
   pohybových příkazů končetiny a postavy a tlačítko "Reset" pro 
   nastavení končetin postavy do jejich původní polohy.
   
   ------
   Příkazy pro končetinu:
    
     (limbName | limbNo) (fwd|f|turn|t|side|s) [ angleChg ]
   
   fwd = kladné otočení kolem osy x
   turn = kladné otočení kolem kolem osy y
   side = kladné otočení kolem osy z

   Lze použít jak jméno tak i číslo končetiny. Příkazy se vypisují
   na standardní výstup při spuštění aplikace Mover3D.

   Není-li uveden parametr angleChg, použije se výchozí úhel o velikost
   5 stupňů. Úhel může být také záporný.

   Úhel, který by dostal končetinu mimo její stanovený úhlovy rozsah,
   je ignorován (vypíše se chybové hlášení).

   ------
   Příkazy pro postavu:

     dopředu | dozadu | doleva | doprava | nahoru | dolů | otočení ve směru h.r. | otočení proti h.r.
      f      |   b    |  l     |   r     |    u   |  d   |             c         |        cc
 
   Pro všechny příkazy existují klávesové zkratky zpracovávané třídou LocationBeh.

   -------
   
   Do textového vstupního pole lze zadat Vícero příkazů oddělených čárkami.
*/

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;


class CommandsPanel extends JPanel
{
  // konstanty pro pohyb postavy
  private final static int FWD = 0;
  private final static int BACK = 1;
  private final static int LEFT = 2;
  private final static int RIGHT = 3;
  private final static int UP = 4;
  private final static int DOWN = 5;

  private final static int CLOCK = 0;   // otočení ve směru
  private final static int CCLOCK = 1;  // a proti směru hodinových ručiček

  // konstanty pro osy
  private final static int X_AXIS = 0;
  private final static int Y_AXIS = 1;
  private final static int Z_AXIS = 2;


  private Figure figure;
  
  
  public CommandsPanel(Figure fig)
  {
    figure = fig;
    
    setLayout( new FlowLayout() );
    add( new JLabel("Příkazy:") );

    // textové pole pro zadávání příkazů
    JTextField commsTF = new JTextField(35);
    add(commsTF);
    commsTF.addActionListener( new ActionListener() {
      public void actionPerformed(ActionEvent e)
      {  processComms(e.getActionCommand()); }
    });

    // tlačítko reset
    JButton resetBut = new JButton("Reset");
    add(resetBut);
    resetBut.addActionListener( new ActionListener() {
      public void actionPerformed(ActionEvent e)
      {  figure.reset(); }
    });
  } // konec metody: CommandsPanel()
 
 

  private void processComms(String input)
  // zpracuje sekvenci příkazů končetiny/postavy
  { if (input == null)
      return;

    String[] commands = input.split(",");  // rozděl vstup do jednotlivých příkazů

    StringTokenizer toks;
    for (int i=0; i < commands.length; i++) {
      toks = new StringTokenizer( commands[i].trim() );
      if (toks.countTokens() == 3)         // 3-argumentový příkaz končetiny
        limbCommand( toks.nextToken(), toks.nextToken(), toks.nextToken() );
      else if (toks.countTokens() == 2)    // 2-argumentový příkaz končetiny s výchozí hodnotou úhlu
        limbCommand( toks.nextToken(), toks.nextToken(), "5");  // neefektivní
      else if (toks.countTokens() == 1)    // 1-argumentový příkaz postavy
        figCommand( toks.nextToken() );
      else
        System.out.println("Neplatný příkaz: " + commands[i]);
    }
  }  // konec metody: processComms()



  private void limbCommand(String limbName, String opStr, String angleStr)
  /* Zpracuje příkaz končetiny ve formě:
             (limbName | limbNo) (fwd|f|turn|t|side|s) angleChg
  */
  { // získej číslo končetiny
    int limbNo = -1;
    try {
      limbNo = figure.checkLimbNo( Integer.parseInt(limbName) );
    }
    catch(NumberFormatException e) 
    {  limbNo = figure.findLimbNo(limbName);  }   // zobraz jméno na číslober

    if (limbNo == -1) {
      System.out.println("Neplatný identifikátor končetiny: " + limbName);
      return;
    }

    // získej změnu úhlu
    double angleChg = 0;
    try {
      angleChg = Double.parseDouble(angleStr);
    }
    catch(NumberFormatException e) 
    { System.out.println("Neplatná změna úhlu: " + angleStr); }

    if (angleChg == 0) {
      System.out.println("Změna úhlu je 0, takže neděláme nic");
      return;
    }

    // extrahuj osy rotace z operace pro končetinu
    int axis;
    if (opStr.equals("fwd") || opStr.equals("f"))
      axis = X_AXIS;
    else if (opStr.equals("turn") || opStr.equals("t"))
      axis = Y_AXIS;
    else if (opStr.equals("side") || opStr.equals("s"))
      axis = Z_AXIS;
    else {
      System.out.println("Neznámá operace končetiny: " + opStr);
      return;
    }

    // aplikuj příkaz na končetinu
    // System.out.println("Příkaz:  limbNo & axis/angleChg: " + 
    //                         limbNo + " & " + axis + "/" + angleChg );
    figure.updateLimb(limbNo, axis, angleChg);

  }   // konec metody: limbCommand()


  private void figCommand(String opStr)
  /* Zpracuje příkaz postavy ve tvar:
     dopředu | dozadu | doleva | doprava | nahoru | dolů | otočení ve směru h.r. | otočení proti h.r.
      f      |   b    |  l     |   r     |    u   |  d   |             c         |        cc
  */
  { if (opStr.equals("fwd") || opStr.equals("f"))
      figure.doMove(FWD);
    else if (opStr.equals("back") || opStr.equals("b"))
      figure.doMove(BACK);
    else if (opStr.equals("left") || opStr.equals("l"))
      figure.doMove(LEFT);
    else if (opStr.equals("right") || opStr.equals("r"))
      figure.doMove(RIGHT);
    else if (opStr.equals("up") || opStr.equals("u"))
      figure.doMove(UP);
    else if (opStr.equals("down") || opStr.equals("d"))
      figure.doMove(DOWN);
    else if (opStr.equals("clock") || opStr.equals("c"))
      figure.doRotateY(CLOCK);
    else if (opStr.equals("cclock") || opStr.equals("cc"))
      figure.doRotateY(CCLOCK);
    else {
      System.out.println("Neznámý příkaz pro postavu: " + opStr);
      return;
    }
  }  // konec metody: figCommand()


} // konec třídy: CommandsPanel
