home *** CD-ROM | disk | FTP | other *** search
/ Java Programmer's Toolkit / Java Programmer's Toolkit.iso / applets / dance / classes / dance.jav < prev    next >
Encoding:
Text File  |  1995-11-08  |  33.9 KB  |  1,281 lines

  1. /*-
  2.  * Copyright (c) 1995 by Georg Hessmann.
  3.  * All Right Reserved.
  4.  *
  5.  * Dance.java    1.0,  25 Aug 1995
  6.  *              1.1,  13 Sep 1995
  7.  *
  8.  *
  9.  */
  10.  
  11. import java.io.InputStream;
  12. import java.lang.Math;
  13. import java.net.URL;
  14. import java.util.Stack;
  15.  
  16. import java.awt.*;
  17.  
  18. import java.applet.AudioClip;
  19.  
  20. import Floor;
  21. import Foot;
  22. import Figur;
  23. import Button;
  24. import MEXButtonList;
  25.  
  26. import SlowWaltz;
  27. import Tango;
  28. import SlowFox;
  29. import Quickstep;
  30.  
  31. // import ChoiceWin;
  32.  
  33.  
  34.  
  35. /**
  36.  * Dance - java.applet.Applet<P>
  37.  *
  38.  * java.applet.Applet for learning how to dance.<P>
  39.  *
  40.  * You can choose one of four dances and for every
  41.  * dance one of some figures and one of some music
  42.  * titels and view the animation of the figur
  43.  * synchron to the music.<P>
  44.  *
  45.  * The applet uses three threads for the animation
  46.  * and does an gread effort to make the animation
  47.  * as flickerless as possible.<P>
  48.  *
  49.  * Three attributes are currently supported:<br>
  50.  * <tt>english</tt> - use english texts<br>
  51.  * <tt>audio</tt> - default audio on/off<br>
  52.  * <tt>fatborder</tt> - use fat or thin border for the buttons.<P>
  53.  *
  54.  * <dl><dt><b>Disclaimer:</b>
  55.  * <dd>Sorrie, my Java is better than my english.
  56.  *             (My dancing is even better. :)
  57.  * </dl>
  58.  *
  59.  * @see Figur
  60.  * @see Floor
  61.  * @see Foot
  62.  * @see Button
  63.  * @see MEXButtonList
  64.  * @see MEXButton
  65.  * @see ToggleButton
  66.  * @see Step
  67.  *
  68.  * @version 1.1, 13 Sep 1995
  69.  * @author Georg Heßmann
  70.  */
  71.  
  72. public class Dance extends java.applet.Applet {
  73.  
  74.   /** current version */
  75.   static final float version = 1.1f;
  76.  
  77.   /** info about the implemented parameters */
  78.   static String[][] paramInfo_eng = {
  79.     { "english",   "boolean", "use english strings" },
  80.     { "audio",     "boolean", "default music on or off" },
  81.     { "fatborder", "boolean", "draw the buttons a bit heavier" }
  82.   };
  83.   
  84.   static String[][] paramInfo_ger = {
  85.     { "english",   "boolean", "verwende englische Texte" },
  86.     { "audio",     "boolean", "Musik per Default an oder aus" },
  87.     { "fatborder", "boolean", "draw the buttons a bit heavier" }
  88.   };
  89.   
  90.  
  91.   /** Use english or german for the strings */
  92.   public boolean engl = false;        // soll englischer Text erscheinen?
  93.  
  94.   /** Foot object. Needed for drawing foots. */
  95.   public Foot    foots;
  96.  
  97.   /** Font used for the applet titel */
  98.   public Font    titleFont;
  99.  
  100.   /** Font used for the sub-titels*/
  101.   public Font     choiceFont;
  102.  
  103.   /** Small font, currently not used. */
  104.   public Font     smallFont;
  105.  
  106.   /** Small font bold. Used for showing the current selection. */
  107.   public Font     smallFontBld;
  108.  
  109.   /** Font used for the buttons. */
  110.   public Font     buttonFont;
  111.  
  112.   /** Bold font used for the buttons. */
  113.   public Font     buttonFontBld;
  114.  
  115.   static final String serverHost = "tech-www.informatik.uni-hamburg.de";
  116.  
  117.   /* resize the applet if, the internal size has changed */
  118.   /* or use always the biggest size. */
  119.   final boolean noResize = false;
  120.   final int initXSize = 575;
  121.   final int initYSize = 545;
  122.  
  123.   /* bisherige maximale Groesse */
  124.   int maxXsize = 0;
  125.   int maxYsize = 0;
  126.  
  127.   boolean clear_floor_border = false;    // soll der Bereich um das Parket
  128.   // neu gezeichnet werden? (Fuesse die ueberstanden)
  129.  
  130.   boolean repaintAll  = true;
  131.   boolean repaintText    = false;  // nur der veraenderliche Text ist betroffen
  132.   boolean repaintButtons = false;  // Main-Buttons sind neu zu zeichnen
  133.  
  134.   boolean takeStepBack = false;
  135.  
  136.   /**
  137.    * Currently active figur.
  138.    */
  139.   public Figur figur;
  140.  
  141.  
  142.   
  143.   // Nummern der einzelnen Buttons (Tanznummern == Array-Index!)
  144.   static final int BslowW  = 0;
  145.   static final int Btango  = 1;
  146.   static final int BslowF  = 2;
  147.   static final int Bquick  = 3;
  148.   static final int Bshow   = 4;
  149.   static final int Binfo   = 5;
  150.   static final int Bmhelp  = 6;    // main help
  151.   static final int Bahelp  = 7;    // animation help
  152.   static final int Bpmusic = 8;    // play/test music
  153.   static final int Bstep   = 10;
  154.   static final int Bback   = 11;
  155.   static final int Bplay   = 12;
  156.   static final int Bmenu   = 13;
  157.   static final int Bsound  = 14;
  158.   static final int Bcomm   = 15;
  159.   static final int Bfigur0 = 20;
  160.   static final int Bmusic0 = 30;
  161.  
  162.   static String danceNames[];
  163.   static String figurNames[][];
  164.   static String musicNames[][];
  165.  
  166.   /*
  167.   static final String figurNames_ger[][] = {
  168.     SlowWaltz.FigNames_ger, Tango.FigNames_ger,
  169.     SlowFox.FigNames_ger, Quickstep.FigNames_ger
  170.   };
  171.  
  172.   static final String figurNames_eng[][] = {
  173.     SlowWaltz.FigNames_eng, Tango.FigNames_eng,
  174.     SlowFox.FigNames_eng, Quickstep.FigNames_eng
  175.   };
  176.   */
  177.  
  178.   static final String musicNames_ger[][] =
  179.   {
  180.     /* Langsamer Walzer */
  181.        { "Ohne Musik", "I Wonder Why (Curtis Stigers)",
  182.          "True Love (Ambros Seelos)" } ,
  183.     /* Tango */
  184.        { "Ohne Musik", "Adios Pampa Mia (Ambros Seelos)" } ,
  185.     /* Slow-Fox */
  186.        { "Ohne Musik", "Java Jive (Manhattan Transfer)",
  187.          "Witchcraft (Frank Sinatra)", "Far Gone Now (Vaya Con Dios)",
  188.      "New York New York (Frank Sinatra)", "Magic Love (Ambros Seelos)" } ,
  189.     /* Quickstep */
  190.        { "Ohne Musik", "Nah Neh Nah (Vaya Con Dios)",
  191.          "I Get A Kick Out Of You (Frank Sinatra)",
  192.          "Dancing Fever (Ambros Seelos)"  }
  193.   };
  194.  
  195.  
  196.   static final String musicNames_eng[][] =
  197.   {
  198.     /* Langsamer Walzer */
  199.        { "No Music", "I Wonder Why (Curtis Stigers)", "True Love (Ambros Seelos)" } ,
  200.     /* Tango */
  201.        { "No Music", "Adios Pampa Mia (Ambros Seelos)" } ,
  202.     /* Slow-Fox */
  203.        { "No Music", "Java Jive (Manhattan Transfer)",
  204.          "Witchcraft (Frank Sinatra)", "Far Gone Now (Vaya Con Dios)",
  205.          "New York New York (Frank Sinatra)", "Magic Love (Ambros Seelos)" } ,
  206.     /* Quickstep */
  207.        { "No Music", "Nah Neh Nah (Vaya Con Dios)",
  208.          "I Get A Kick Out Of You (Frank Sinatra)",
  209.          "Dancing Fever (Ambros Seelos)" }
  210.   };
  211.  
  212.   static final String musicFiles[][] =
  213.   {
  214.     /* Langsamer Walzer */
  215.        { null, "audio/IWonderWhy", "audio/TrueLove" } ,
  216.     /* Tango */
  217.        { null, "audio/AdiosPampaMia" } ,
  218.     /* Slow-Fox */
  219.        { null, "audio/JavaJive", "audio/witch", "audio/FarGoneNow",
  220.      "audio/NewYorkNewYork", "audio/MagicLove" } ,
  221.     /* Quickstep */
  222.        { null, "audio/NahNehNah", "audio/GetAKick",
  223.          "audio/DancingFever" }
  224.   };
  225.  
  226.   static final int musicTempo[][] =
  227.   {
  228.     /* Langsamer Walzer */
  229.        { 0, 32, 33 } ,        // eigentlich 30
  230.     /* Tango */
  231.        { 0, 36 } ,
  232.     /* Slow-Fox */
  233.        { 0, 26, 30, 33, 29, 32 } ,
  234.     /* Quickstep */
  235.        { 0, 28, 22, 26 }          // 52
  236.   };
  237.  
  238.   AudioClip audioAnim = null;
  239.   AudioClip audioPlay = null;
  240.  
  241.   MEXButtonList mexDance;
  242.   MEXButtonList mexFigur;
  243.   MEXButtonList mexMusic;
  244.  
  245.   //Stack layoutStack;        // alle Layout-Dinge, die bisher add()'ed wurden
  246.   Panel innerPanel = null;
  247.  
  248.   // ChoiceWin cWin = null;
  249.   
  250.  
  251.   int choosedDanceNum = 0;  // welcher Tanz wurde ausgewaehlt?
  252.   int choosedFigurNum = 0;  // welche Figur (des Tanzes) wurde ausgewaehlt?
  253.   int choosedMusicNum = 0;  // dito. Musik
  254.  
  255.   boolean audioON;          // soll Musik gespielt werden?
  256.   boolean defAudioON;        // attribut value
  257.  
  258.   boolean useCommentHT;        // show heal/toe or slow/quick
  259.   
  260.  
  261.   /** Should have the buttons a two pixel border or only a one pixel border. */
  262.   public boolean fatBorder;    // Buttons with fat border?
  263.  
  264.  
  265.   /**
  266.    * java.applet.Applet initialization function.
  267.    * Loads some fonts, reads the attributes "english", "audio" and
  268.    * "fatborder".
  269.    */
  270.   public void init()
  271.   {
  272.     titleFont     = new java.awt.Font("Helvetica", Font.BOLD, 24);
  273.     choiceFont      = new java.awt.Font("Helvetica", Font.PLAIN, 18);
  274.     smallFont     = new java.awt.Font("Helvetica", Font.PLAIN, 14);
  275.     smallFontBld  = new java.awt.Font("Helvetica", Font.BOLD, 14);
  276.     buttonFont       = new java.awt.Font("Helvetica", Font.PLAIN, 12);
  277.     buttonFontBld = new java.awt.Font("Helvetica", Font.BOLD, 12);
  278.  
  279.     /* hm, gibt erstmal (ohne g) keinen default Font mehr
  280.     if (titleFont     == null) titleFont     = font;
  281.     if (choiceFont    == null) choiceFont    = font;
  282.     if (smallFont     == null) smallFont     = font;
  283.     if (smallFontBld  == null) smallFontBld  = font;
  284.     if (buttonFont    == null) buttonFont    = font;
  285.     if (buttonFontBld == null) buttonFontBld = font;
  286.     */
  287.  
  288.     /* static variable -> not reentrant :( */
  289.     Button.app        = this;
  290.  
  291.     /* english or german texts? */
  292.     /*
  293.     String attr = getParameter("english");
  294.     if (attr != null) {
  295.       engl = (attr.compareTo("false") != 0);    // nur false schaltet engl aus
  296.     }
  297.     else {
  298.       engl = false;                // oder halt gar kein Attr
  299.     }
  300.     */
  301.     engl = true;
  302.  
  303.     /* initializes (german/english) some strings */
  304.     /*
  305.     danceNames[0] = (engl) ? SlowWaltz.Name_eng : SlowWaltz.Name_ger;
  306.     danceNames[1] = (engl) ? Tango    .Name_eng : Tango    .Name_ger;
  307.     danceNames[2] = (engl) ? SlowFox  .Name_eng : SlowFox  .Name_ger;
  308.     danceNames[3] = (engl) ? Quickstep.Name_eng : Quickstep.Name_ger;
  309.     */
  310.     danceNames = new String[4];
  311.     danceNames[0] = (engl) ? "English Waltz" : "Langsamer Walzer";
  312.     danceNames[1] = (engl) ? "Tango" : "Tango";
  313.     danceNames[2] = (engl) ? "Slowfoxtrot" : "Slow Fox";
  314.     danceNames[3] = (engl) ? "Foxtrott" : "Quickstep";
  315.  
  316.     figurNames = new String[4][];
  317.     figurNames[0] = new String[2];
  318.     figurNames[0][0] = (engl) ? "Natural Turn" : "Rechtsdrehung";
  319.     figurNames[0][1] = (engl) ? "Whisk" : "Wischer";
  320.     figurNames[1] = new String[3];    // Tango.FigNames_eng;
  321.     figurNames[1][0] = (engl) ? "Left Turn" : "Linksdrehung";
  322.     figurNames[1][1] = (engl) ? "Rock Turn" : "Wiegeschrittdrehung";
  323.     figurNames[1][2] = (engl) ? "Outside Swivel, Brush Tap" : "Linksgedrehte Kehre + Brush Tap";
  324.     figurNames[2] = new String[2];
  325.     figurNames[2][0] = (engl) ? "Feather Step" : "Federschritt";
  326.     figurNames[2][1] = (engl) ? "Left Turn" : "Linksdrehung";
  327.     figurNames[3] = new String[2];
  328.     figurNames[3][0] = (engl) ? "Natural Turn" : "Rechtsdrehung";
  329.     figurNames[3][1] = (engl) ? "ChassΘ Reverse Turn" : "Wechselschritt-Linksdrehung" ;
  330.     if (engl) {
  331.       // figurNames = figurNames_eng;
  332.       musicNames = musicNames_eng;
  333.       // figurNames = new String[4][];
  334.       // figurNames[0] = SlowWaltz.FigNames_eng;
  335.       // figurNames[1] = Tango.FigNames_eng;
  336.       // figurNames[2] = SlowFox.FigNames_eng;
  337.       // figurNames[3] = Quickstep.FigNames_eng;
  338.     }
  339.     else {
  340.       //figurNames = figurNames_ger;
  341.       musicNames = musicNames_ger;
  342.       // figurNames = new String[4][];
  343.       // figurNames[0] = SlowWaltz.FigNames_ger;
  344.       // figurNames[1] = Tango.FigNames_ger;
  345.       // figurNames[2] = SlowFox.FigNames_ger;
  346.       // figurNames[3] = Quickstep.FigNames_ger;
  347.     }
  348.  
  349.     /* should be "no music" or the first music title the default? */
  350.     /*
  351.     attr = getParameter("audio");
  352.     if (attr != null) {
  353.       defAudioON = (attr.compareTo("false") != 0);    // nur false schaltet audio aus
  354.     }
  355.     else {
  356.       defAudioON = false;                // oder halt gar kein Attr
  357.     }
  358.     */
  359.     defAudioON = false;
  360.  
  361.     if (defAudioON) choosedMusicNum = 1;    // first music file
  362.     else            choosedMusicNum = 0;    // no music
  363.  
  364.     audioON = defAudioON;
  365.  
  366.     /* buttons with 1 or 2 pixel border? */
  367.     /*
  368.     attr = getParameter("fatborder");
  369.     if (attr != null) {
  370.       fatBorder = (attr.compareTo("false") != 0);
  371.     }
  372.     else {
  373.       fatBorder = false;            // oder halt gar kein Attr
  374.     }
  375.     */
  376.     fatBorder = false;
  377.     
  378.     /* always start with displaying the toe/heal string */
  379.     useCommentHT = true;
  380.  
  381.     /* initialize the Foot object (load it first time a figur is allocated) */
  382.     foots = null;
  383.  
  384.     /* we are in the main menu, no figur loaded */
  385.     figur = null;
  386.  
  387.     innerPanel = null;
  388.  
  389.     setBackground(Color.lightGray);
  390.  
  391.     /* some initializations, which occures after every page change */
  392.     /* (main page <--> animation page)                    */
  393.     init_post();
  394.     
  395.     // getAppletContext().showStatus("Done.");
  396.   }
  397.  
  398.   /**
  399.    * Initialization function which will called after every page-change.
  400.    * (There are two 'pages': main-menu page and animation page.
  401.    */
  402.   private void init_post()
  403.   {
  404.     if (innerPanel != null) {
  405.       remove(innerPanel);
  406.       innerPanel.removeAll();
  407.       innerPanel = null;
  408.     }
  409.     
  410.     if (figur != null) {
  411.       /* figur != null  ->  animation page */
  412.       
  413.       int xsize = figur.RightEdge() + 20;
  414.       int ysize = figur.BottomEdge() + 20;
  415.  
  416.       /* niemals verkleinern? */
  417.       if (noResize) {
  418.     if (xsize > maxXsize) maxXsize = xsize;
  419.     if (ysize > maxYsize) maxYsize = ysize;
  420.       }
  421.       else {
  422.     maxXsize = xsize;
  423.     maxYsize = ysize;
  424.       }
  425.       
  426.       resize(maxXsize, maxYsize);
  427.  
  428.       /* free all buttons (of main page) */
  429.       Button.freeAll();
  430.  
  431.       int ypos    = figur.hfloor.BottomEdgeParket();
  432.       int bheight = 20;
  433.       
  434.       Button dummy;
  435.  
  436.       ypos -= bheight;
  437.       dummy = new Button(Bmenu, (engl) ? "menu" : "Menⁿ", 15, ypos,
  438.              figur.hfloor.LeftEdge() - 30, bheight, buttonFontBld);
  439.       ypos -= bheight + 10;
  440.       dummy = new Button(Bback, (engl) ? "step backw." : "rⁿckwΣrts", 15, ypos,
  441.              figur.hfloor.LeftEdge() - 30, bheight, buttonFont);
  442.       ypos -= bheight + 5;
  443.       dummy = new Button(Bstep, (engl) ? "step forw." : "vorwΣrts", 15, ypos,
  444.              figur.hfloor.LeftEdge() - 30, bheight, buttonFont);
  445.       ypos -= bheight + 5;
  446.       dummy = new Button(Bplay, (engl) ? "play" : "Animation", 15, ypos,
  447.              figur.hfloor.LeftEdge() - 30, bheight, buttonFontBld);
  448.  
  449.       if (choosedMusicNum != 0) {
  450.     ypos -= bheight + 10;
  451.     dummy = new ToggleButton(Bsound,
  452.                  (engl) ? "use audio"   : "Ton an",
  453.                  (engl) ? "slow motion" : "Zeitlupe",
  454.                  15, ypos,
  455.                  figur.hfloor.LeftEdge() - 30, bheight,
  456.                  buttonFont, buttonFont, audioON);
  457.     ypos -= bheight + 5;
  458.       }
  459.       else {
  460.     ypos -= bheight + 10;
  461.       }
  462.  
  463.       /* setup the comment string */
  464.       if (useCommentHT) figur.useComStrHT();
  465.       else          figur.useComStrTime();
  466.  
  467.       dummy = new ToggleButton(Bcomm,
  468.                    (engl) ? "footwork" : "Fu▀arbeit",
  469.                    (engl) ? "rhythm" : "Rhythmus", 
  470.                    15, ypos,
  471.                    figur.hfloor.LeftEdge() - 30, bheight,
  472.                    buttonFont, buttonFont, useCommentHT);
  473.  
  474.       ypos -= bheight + 10;
  475.       dummy = new Button(Bahelp, (engl) ? "help" : "Hilfe", 15, ypos,
  476.              figur.hfloor.LeftEdge() - 30, bheight, buttonFont);
  477.  
  478.     }
  479.     else {
  480.       /* figur == null  ->  main page */
  481.       
  482.       int xsize = initXSize;
  483.       int ysize = initYSize;
  484.       
  485.       /* niemals verkleinern...? */
  486.       if (noResize) {
  487.     if (xsize > maxXsize) maxXsize = xsize;
  488.     if (ysize > maxYsize) maxYsize = ysize;
  489.       }
  490.       else {
  491.     maxXsize = xsize;
  492.     maxYsize = ysize;
  493.       }
  494.  
  495.       resize(maxXsize, maxYsize);
  496.  
  497.       audioON = defAudioON;
  498.       CreateMainButtons();
  499.     }
  500.   }
  501.  
  502.   public void start()
  503.   {
  504.     /*
  505.     if (figur == null) {
  506.       initMainLayout();
  507.     }
  508.     if (cWin == null) {
  509.       cWin = new ChoiceWin(this);
  510.     }
  511.     */
  512.   }
  513.  
  514.  
  515.   /**
  516.    * java.applet.Applet function: paint()
  517.    * Redraw completly the main (figur==null) or animation page (figur!=null).
  518.    */
  519.   public void paint(Graphics g)
  520.   {
  521.     //System.out.println("paint");
  522.     
  523.     setBackground(Color.lightGray);
  524.  
  525.     if (figur != null) paint_figur(g);
  526.     else            paint_main(g);
  527.     
  528.     Button.drawAll(g);
  529.   }
  530.  
  531.   /**
  532.    * java.applet.Applet function: update()
  533.    * Redraw only the changed things.
  534.    */
  535.   public void update(Graphics g)
  536.   {
  537.     //System.out.println("update");
  538.  
  539.     setBackground(Color.lightGray);
  540.     
  541.     if (figur != null) update_figur(g);
  542.     else            update_main(g);
  543.  
  544.     Button.drawChanged(g);
  545.   }
  546.     
  547.  
  548.  
  549.   /**
  550.    * total redraw of the animation page.
  551.    */
  552.   private void paint_figur(Graphics g)
  553.   {
  554.     if (!figur.everPaint) {
  555.       figur.everPaint = true;
  556.     }
  557.  
  558.     // Bug? clearRect() doesn't respect clipRect().
  559.     if (!takeStepBack) g.clearRect(1,1,size().width-2,size().height-2);
  560.     // loesche alles ausser dem Rahmen
  561.  
  562.     g.draw3DRect(0, 0, size().width-1, size().height-1, true);
  563.     figur.drawTitel(g);
  564.  
  565.     figur.dfloor.RedrawFloor();    // die muessen nun auch den Hintergrund
  566.     figur.hfloor.RedrawFloor();    // neu zeichnen.
  567.  
  568.     figur.dfloor.paint(g);
  569.     figur.hfloor.paint(g);
  570.  
  571.     figur.drawNum(g, false);
  572.   }
  573.  
  574.   /**
  575.    * updtae of the animation page. Draw only new things.
  576.    */
  577.   private void update_figur(Graphics g)
  578.   {
  579.     // ich loesche nun nie mehr den gesamten Hintergrund
  580.     // d.h. wenne s etwas zu loeschen gibt, dann muss ich das expliziet tun
  581.     // siehe clear_floor_border
  582.  
  583.     if (!figur.everPaint) {
  584.       paint_figur(g);
  585.     }
  586.     
  587.     if (clear_floor_border) {
  588.       // oben rueber loeschen
  589.       g.clearRect(figur.hfloor.LeftEdge()-10, figur.hfloor.TopEdge()-10,
  590.           figur.RightEdge()-figur.hfloor.LeftEdge()+20,
  591.           10);
  592.       // unten drunter loeschen
  593.       g.clearRect(figur.hfloor.LeftEdge()-10, figur.hfloor.BottomEdgeParket(),
  594.           figur.RightEdge()-figur.hfloor.LeftEdge()+20,
  595.           11);
  596.       // links
  597.       g.clearRect(figur.hfloor.LeftEdge()-20, figur.hfloor.TopEdge()-10,
  598.           20,
  599.           figur.hfloor.BottomEdgeParket()-figur.hfloor.TopEdge()-175);
  600.       g.clearRect(figur.hfloor.LeftEdge()-15, figur.hfloor.TopEdge()-10,
  601.           15,
  602.           figur.hfloor.BottomEdgeParket()-figur.hfloor.TopEdge()+20);
  603.       // Mitte
  604.       g.clearRect(figur.hfloor.RightEdge(), figur.hfloor.TopEdge()-10,
  605.           figur.dfloor.LeftEdge()-figur.hfloor.RightEdge(),
  606.           figur.hfloor.BottomEdgeParket()-figur.hfloor.TopEdge()+20);
  607.       // rechts
  608.       g.clearRect(figur.dfloor.RightEdge(),figur. hfloor.TopEdge()-10,
  609.           figur.RightEdge()-figur.dfloor.RightEdge()+15,
  610.           figur.hfloor.BottomEdgeParket()-figur.hfloor.TopEdge()+20);
  611.  
  612.       clear_floor_border = false;
  613.       figur.dfloor.RedrawFloor();    // die muessen nun auch den Hintergrund
  614.       figur.hfloor.RedrawFloor();    // neu zeichnen.
  615.     }
  616.  
  617.     figur.hfloor.paint(g);
  618.     figur.dfloor.paint(g);
  619.  
  620.     figur.drawNum(g, true);
  621.  
  622.     
  623.     if (takeStepBack) { 
  624.       Graphics dg = figur.dfloor.installClipRect(g);
  625.       paint_figur(dg);
  626.  
  627.       Graphics hg = figur.hfloor.installClipRect(g);
  628.       paint_figur(hg);
  629.       
  630.       takeStepBack = false;
  631.     }
  632.     
  633.   }
  634.  
  635.   /**
  636.    * total redraw of the main-menu page.
  637.    */
  638.   private void paint_main(Graphics g)
  639.   {
  640.     Font oldf = g.getFont();
  641.       
  642.     g.clearRect(0, 0, size().width, size().height);
  643.  
  644.     //g.draw3DRect(0, 0, size().width, size().height, true);
  645.     g.draw3DRect(0, 0, initXSize-1, initYSize-1, true);
  646.  
  647.     g.setFont(titleFont);
  648.  
  649.     String s;
  650.     
  651.     if (engl) s = "How to Learn Dance with HotJava";
  652.     else      s = "Tanzen lernen leicht gemacht";
  653.  
  654.     int l = g.getFontMetrics(titleFont).stringWidth(s);
  655.     g.drawString(s, 295-l/2, 35);
  656.  
  657.     g.setFont(oldf);
  658.     if (engl) {
  659.       g.drawString("Long time ago, you have had a dancing course, but" +
  660.            " because of no practice you have", 20, 70);
  661.       g.drawString("forgotten most of the dancing steps?", 20, 87);
  662.       g.drawString("No problem! With Java-Dance you can watch an animation" +
  663.            " of different figures,", 30, 104);
  664.       g.drawString("and get information about rhythm and footwork." +
  665.            " Come on and dance!", 20, 121);
  666.     }
  667.     else {
  668.       g.drawString("Sie haben vor Urzeiten mal einen Tanzkurs gemacht," +
  669.            " haben aber mangels ▄bung alles", 20, 70);
  670.       g.drawString("wieder vergessen? Kein Problem! Mit Java-Dance k÷nnen" +
  671.            " Sie sich verschiedene ", 20, 87);
  672.       g.drawString("Standard Figuren ansehen (animiert mit Ton" +
  673.            " oder Schritt fⁿr Schritt).", 20, 104);
  674.       g.drawString("Dazu gibt es zu jedem Schritt Informationen" +
  675.            " ⁿber Rythmus und Fu▀arbeit.", 20, 121);
  676.     }
  677.       
  678.     g.setFont(choiceFont);
  679.  
  680.     if (engl) {
  681.       g.drawString("Current selection:", 20, 150);
  682.       g.drawString("Available dances:", 20, 220);
  683.       g.drawString("Available dance-figures for current dance:", 20, 300);
  684.       g.drawString("Available music for current dance:", 20, 410);
  685.     }
  686.     else {
  687.       g.drawString("Derzeit ausgewΣhlt:", 20, 150);
  688.       g.drawString("Verfⁿgbare TΣnze:", 20, 220);
  689.       g.drawString("Verfⁿgbare Figuren fⁿr diesen Tanz:", 20, 300);
  690.       g.drawString("Verfⁿgbare Musik fⁿr diesen Tanz:", 20, 410);
  691.     }
  692.  
  693.     g.setFont(oldf);
  694.  
  695.     repaintText = true;
  696.     update_main(g);
  697.   }
  698.  
  699.   /**
  700.    * update of the main-menu page. Redraw only the texts or buttons.
  701.    */
  702.   private void update_main(Graphics g)
  703.   {
  704.     if (repaintAll) {
  705.       repaintAll     = false;
  706.       repaintText    = true;
  707.       repaintButtons = true;
  708.       paint_main(g);
  709.     }
  710.  
  711.     if (repaintText) {
  712.       repaintText = false;
  713.     
  714.       Font oldf = g.getFont();
  715.  
  716.       g.setFont(smallFontBld);
  717.       g.clearRect(40, 160, initXSize-41, 30);
  718.       g.drawString(danceNames[choosedDanceNum] + ", " +
  719.            ((figurNames[choosedDanceNum].length > 0)
  720.               ? figurNames[choosedDanceNum][choosedFigurNum]
  721.               : "(none)") + ", " +
  722.            ((musicNames[choosedDanceNum].length > 0)
  723.               ? musicNames[choosedDanceNum][choosedMusicNum]
  724.               : "(none)"), 40, 180);
  725.       g.setFont(oldf);
  726.     }
  727.     
  728.     if (repaintButtons) {
  729.       repaintButtons = false;
  730.  
  731.       // Figur-Buttons loeschen
  732.       g.clearRect(40, 310, initXSize-41, 60);
  733.  
  734.       // Musik-Buttons loeschen
  735.       g.clearRect(40, 415, initXSize-41, 85);
  736.  
  737.       //Button.drawAll(g);
  738.     }
  739.   }
  740.  
  741.  
  742.   /*
  743.   private void initMainLayout()
  744.   {
  745.     if (innerPanel != null) return;
  746.     
  747.     innerPanel = new Panel();
  748.  
  749.     try {
  750.       //innerPanel.setLayout(new GridLayout(10, 5, 5, 5));
  751.       String s;
  752.     
  753.       if (engl) s = "How to Learn Dance with HotJava";
  754.       else      s = "Tanzen lernen leicht gemacht";
  755.  
  756.       Label l = new Label(s, Label.CENTER);
  757.       l.setFont(titleFont);
  758.       innerPanel.add(l);
  759.       //l.move(100, 100);
  760.     }
  761.     catch (IllegalArgumentException e)
  762.     {
  763.       ;
  764.     }
  765.     add(innerPanel);
  766.     show();
  767.   }
  768.   */
  769.  
  770.   /*
  771.   public synchronized Component add(Component c)
  772.   {
  773.     layoutStack.push(c);
  774.     return super.add(c);
  775.   }
  776.  
  777.   public synchronized Component add(String s, Component c)
  778.   {
  779.     layoutStack.push(c);
  780.     return super.add(s, c);
  781.   }
  782.  
  783.   public synchronized void removeAllComponents()
  784.   {
  785.     while (!layoutStack.empty()) {
  786.       Component c = (Component)layoutStack.pop();
  787.       remove(c);
  788.     }
  789.   }
  790.   */
  791.   
  792.  
  793.  
  794.   /**
  795.    * java.applet.Applet function: stop()
  796.    * Stops the dancing and the audio.
  797.    */
  798.   public void stop()
  799.   {
  800.     if (figur != null) {
  801.       figur.StopDance();
  802.     }
  803.     else if (audioPlay != null) {
  804.       audioPlay.stop();
  805.       audioPlay = null;
  806.     }
  807.   }
  808.  
  809.  
  810.   /** returns some info about author, version and copyright of the applet */
  811.   public String getAppletInfo()
  812.   {
  813.     return "JDance. Author: Georg He▀mann, Version: " + version +
  814.            ", Copyright (c) 1995, All Rights Reserved.";
  815.   }
  816.  
  817.   /** returns info about the parameters */
  818.   public String[][] getParameterInfo()
  819.   {
  820.     return (engl) ? paramInfo_eng : paramInfo_ger;
  821.   }
  822.  
  823.   /**
  824.    * java.applet.Applet function: mouseDown()
  825.    * Calls button.mouseDown() to check for button hits.
  826.    * @see Button#mouseDown
  827.    */
  828.   public boolean mouseDown(java.awt.Event evt, int x, int y)
  829.   {
  830.     requestFocus();
  831.  
  832.     return Button.mouseDown(x, y);
  833.   }
  834.  
  835.   /**
  836.    * java.applet.Applet function: mouseUp()
  837.    * Calls button.mouseUp() to check for button hits.
  838.    * @see Button#mouseUp
  839.    */
  840.   public boolean mouseUp(java.awt.Event evt, int x, int y)
  841.   {
  842.     return Button.mouseUp(x, y);
  843.   }
  844.  
  845.   /**
  846.    * java.applet.Applet function: mouseDrag()
  847.    * Calls button.mouseDrag() to check for button hits.
  848.    * @see Button#mouseDrag
  849.    */
  850.   public boolean mouseDrag(java.awt.Event evt, int x, int y)
  851.   {
  852.     return Button.mouseDrag(x, y);
  853.   }
  854.  
  855.   /**
  856.    * Initialize the buttons of the main-menu page.
  857.    */
  858.   private void CreateMainButtons()
  859.   {
  860.     Button.freeAll();
  861.  
  862.     mexDance = new MEXButtonList(buttonFontBld);
  863.     for (int i=0; i<danceNames.length; i++) {
  864.       mexDance.NewMEXButton(BslowW + i, danceNames[i],
  865.                 40+130*i, 240, 120, 20, buttonFont);
  866.     }
  867.     mexDance.SetChoosedNum(choosedDanceNum);
  868.  
  869.     mexFigur = new MEXButtonList(buttonFontBld);
  870.     for (int i=0; i<figurNames[choosedDanceNum].length; i++) {
  871.       mexFigur.NewMEXButton(Bfigur0 + i, figurNames[choosedDanceNum][i],
  872.                 40+260*(i%2), 320+25*(i/2), 250, 20, buttonFont);
  873.     }
  874.     mexFigur.SetChoosedNum(choosedFigurNum+Bfigur0);
  875.       
  876.     mexMusic = new MEXButtonList(buttonFontBld);
  877.     for (int i=0; i<musicNames[choosedDanceNum].length; i++) {
  878.       mexMusic.NewMEXButton(Bmusic0 + i, musicNames[choosedDanceNum][i],
  879.                 40+260*(i%2), 425+25*(i/2), 250, 20, buttonFont);
  880.     }
  881.     mexMusic.SetChoosedNum(choosedMusicNum+Bmusic0);
  882.     
  883.     audioON = (choosedMusicNum != 0);
  884.     
  885.     Button dummy;
  886.     dummy = new Button(Binfo,
  887.                (engl) ? "dance info" : "Tanz Info.",
  888.                295 - 100 - 100, 515,
  889.                100, 20, buttonFont);
  890.     dummy = new Button(Bmhelp,
  891.                (engl) ? "help" : "Hilfe",
  892.                295 + 100, 515,
  893.                100, 20, buttonFont);
  894.     dummy = new Button(Bshow,
  895.                (engl) ? "show dance" : "Tanz anzeigen",
  896.                295-50, 515,
  897.                100, 20, buttonFontBld);
  898.  
  899.     dummy = new Button(Bpmusic,
  900.                (engl) ? "test music" : "Musik testen",
  901.                550-80, 390+6,
  902.                80, 20, buttonFont);
  903.  
  904.     repaintButtons = true;
  905.   }
  906.  
  907.  
  908.   public int getCurDance() { return choosedDanceNum; }
  909.   public int getCurFigur() { return choosedFigurNum; }
  910.   public int getCurMusic() { return choosedMusicNum; }
  911.  
  912.   public void setCurDance(int num)
  913.   {
  914.     choosedDanceNum = num;
  915.     choosedFigurNum = 0;
  916.     choosedMusicNum = (defAudioON) ? 1 : 0;
  917.     
  918.     CreateMainButtons();
  919.     repaintText    = true;
  920.  
  921.     //if (cWin != null) cWin.setupMusicMenu();
  922.   }
  923.  
  924.   public void setCurFigur(int num)
  925.   {
  926.     choosedFigurNum = num; 
  927.     repaintText = true;
  928.   }
  929.  
  930.   public void setCurMusic(int num)
  931.   {
  932.     choosedMusicNum = num;
  933.     audioON = (choosedMusicNum != 0);
  934.     repaintText = true;
  935.   }
  936.     
  937.  
  938.   /**
  939.    * Change from the animation page back to the main page.
  940.    */
  941.   public void killFigur()
  942.   {
  943.     figur.StopDance();
  944.     figur = null;
  945.  
  946.     init_post();
  947.  
  948.     repaintAll = true;        // muss komplett neu aufgebaut werden
  949.     repaint();
  950.   }
  951.  
  952.  
  953.   /**
  954.    * Change from the main page to the animation page.
  955.    * Creates an object for the chooseen dance/figur.
  956.    */
  957.   public synchronized void newFigur()
  958.   {
  959.     // getAppletContext().showStatus("Load new dance...");
  960.     if (figur != null) killFigur();
  961.  
  962.     if (audioPlay != null) {
  963.       audioPlay.stop();
  964.       audioPlay = null;
  965.     }
  966.  
  967.     /* (allocates the foot array, but don't load any feets).*/
  968.     if (foots == null) {
  969.       /* verzoegere das Laden der Klasse moeglichst lange */
  970.       foots = new Foot(this);
  971.     }
  972.  
  973.  
  974.     URL audioURL;
  975.     try {
  976.       audioURL = (choosedMusicNum != 0 && musicFiles[choosedDanceNum].length > 0)
  977.     ? new URL(getCodeBase(),
  978.           musicFiles[choosedDanceNum][choosedMusicNum] + "-part.au")
  979.     : null;
  980.     }
  981.     catch (java.net.MalformedURLException e) {
  982.       audioURL = null;
  983.     }
  984.     
  985.     int tempo = musicTempo[choosedDanceNum][choosedMusicNum];
  986.  
  987.     switch (choosedDanceNum) {
  988.      case BslowW:
  989.       figur = new SlowWaltz(this, choosedFigurNum, tempo, audioURL);
  990.       break;
  991.  
  992.      case Btango:
  993.       figur = new Tango    (this, choosedFigurNum, tempo, audioURL);
  994.       break;
  995.  
  996.      case BslowF:
  997.       figur = new SlowFox  (this, choosedFigurNum, tempo, audioURL);
  998.       break;
  999.       
  1000.      case Bquick:
  1001.       figur = new Quickstep(this, choosedFigurNum, tempo, audioURL);
  1002.       break;
  1003.     }
  1004.  
  1005.     // resize - create buttons - ...
  1006.     init_post();
  1007.  
  1008.     // Figur erstmal komplett anzeigen
  1009.     while (figur.DoHStep() >= 0 && figur.DoDStep() >= 0);
  1010.     figur.HideComStr();
  1011.  
  1012.     // getAppletContext().showStatus("Done.");
  1013.     repaint();
  1014.   }
  1015.  
  1016.   /** Should audio played while the animation runs? */
  1017.   public boolean useAudio()
  1018.   {
  1019.     return audioON;
  1020.   }
  1021.  
  1022.   /**
  1023.    * Function will be called if the "menu" button is hit.
  1024.    * Change from the animation page back to the main page.
  1025.    * @see Button#action
  1026.    */
  1027.   public void actionMenuButton()
  1028.   {
  1029.     killFigur();
  1030.   }
  1031.  
  1032.   /**
  1033.    * Function will be called if the "step forw." button is hit.
  1034.    * Does one step forward.
  1035.    * @see Figur#stepForw
  1036.    * @see Button#action
  1037.    */
  1038.   public void actionStepButton()
  1039.   {
  1040.     if (!figur.inSingleStep()) {
  1041.       figur.clearSteps();
  1042.       figur.ShowComStr();
  1043.       clear_floor_border = true;
  1044.       repaint();
  1045.     }
  1046.  
  1047.     figur.stepForw();
  1048.     repaint();
  1049.   }
  1050.  
  1051.   /**
  1052.    * Function will be called if the "step backw." button is hit.
  1053.    * Does one step backward.
  1054.    * @see Figur#stepBackw
  1055.    * @see Button#action
  1056.    */
  1057.   public void actionBackStepButton()
  1058.   {
  1059.     figur.stepBackw();
  1060.     takeStepBack = true;
  1061.     repaint();
  1062.   }
  1063.  
  1064.   /**
  1065.    * Function will be called if the "play" button is hit.
  1066.    * Starts the animation. If an animation is already running, stops it.
  1067.    * @see Button#action
  1068.    */
  1069.   public void actionPlayButton()
  1070.   {
  1071.     if (figur.inSingleStep()) {
  1072.       figur.leaveSingleStep();
  1073.       figur.clearSteps();
  1074.       clear_floor_border = true;
  1075.       repaint();
  1076.     }
  1077.  
  1078.     if (!figur.ThreadsAlive()) {
  1079.       // Alles tot, also komplett neu beginnen
  1080.       figur.clearSteps();
  1081.       clear_floor_border = true;
  1082.       repaint();
  1083.       //try {Thread.sleep(500);} catch (InterruptedException e){}
  1084.  
  1085.       figur.Dance();
  1086.     }
  1087.     else {
  1088.       figur.StopDance();
  1089.       repaint();
  1090.     }
  1091.   }
  1092.  
  1093.   /**
  1094.    * Function will be called if one of the dance buttons are hit.
  1095.    * Sets the other (figur/music) buttons new.
  1096.    * @see Button#action
  1097.    */
  1098.   public void actionDanceButton(int Bnum)
  1099.   {
  1100.     setCurDance(mexDance.GetChoosedNum());
  1101.   }
  1102.  
  1103.   /**
  1104.    * Function will be called, if one of the figur buttons are hit.
  1105.    * @see Button#action
  1106.    */
  1107.   public void actionFigurButton(int Bnum)
  1108.   {
  1109.     setCurFigur(mexFigur.GetChoosedNum() - Bfigur0);
  1110.   }
  1111.  
  1112.   /**
  1113.    * Function will be called, if one of the music buttons are hit.
  1114.    * @see Button#action
  1115.    */
  1116.   public void actionMusicButton(int Bnum)
  1117.   {
  1118.     setCurMusic(mexMusic.GetChoosedNum() - Bmusic0);
  1119.   }
  1120.  
  1121.   /**
  1122.    * Function will be called if the "show dance" button is hit.
  1123.    * Changes from the main page to the animation page.
  1124.    * @see Button#action
  1125.    */
  1126.   public void actionShowButton()
  1127.   {
  1128.     newFigur();
  1129.   }
  1130.  
  1131.   /**
  1132.    * Function will be called if the "dance info" button is hit.
  1133.    * Opens an URL with information about the currently selected dance.
  1134.    * @see Button#action
  1135.    */
  1136.   public void actionInfoButton()
  1137.   {
  1138.     URL url = null;
  1139.  
  1140.     try {
  1141.       switch (choosedDanceNum) {
  1142.        case BslowW:
  1143.     url = new URL("http://" + serverHost + "/dance/LW.html");
  1144.     break;
  1145.  
  1146.        case Btango:
  1147.     url = new URL("http://" + serverHost + "/dance/Tango.html");
  1148.     break;
  1149.  
  1150.        case BslowF:
  1151.     url = new URL("http://" + serverHost + "/dance/Slowfox.html");
  1152.     break;
  1153.  
  1154.        case Bquick:
  1155.     url = new URL("http://" + serverHost + "/dance/Quick.html");
  1156.     break;
  1157.       }
  1158.     }
  1159.     catch (java.net.MalformedURLException e) {
  1160.       url = null;
  1161.     }
  1162.     if (url != null) getAppletContext().showDocument(url);
  1163.   }
  1164.  
  1165.   /**
  1166.    * Function will be called if the "test music" button is hit.
  1167.    * Start playing the selected music.
  1168.    * @see Button#action
  1169.    */
  1170.   public void actionPlayMusicButton()
  1171.   {
  1172.     if (audioPlay != null) {
  1173.       audioPlay.stop();
  1174.       audioPlay = null;
  1175.     }
  1176.     
  1177.     String music = (choosedMusicNum != 0 && musicFiles[choosedDanceNum].length > 0)
  1178.                   ? (musicFiles[choosedDanceNum][choosedMusicNum] + ".au")
  1179.             : null;
  1180.     if (music != null) {
  1181.       URL url;
  1182.       try {
  1183.         url = new URL("http://" + serverHost + "/dance/" + music);
  1184.       }
  1185.       catch (java.net.MalformedURLException e) {
  1186.     url = null;
  1187.       }
  1188.       audioPlay = getAudioClip(url);
  1189.       if (audioPlay != null) {
  1190.     audioPlay.play();
  1191.       }
  1192.     }
  1193.   }
  1194.  
  1195.   /**
  1196.    * Function will be called if the "help" button within the main page is hit.
  1197.    * Open an URL to a help page.
  1198.    * @see Button#action
  1199.    */
  1200.   public void actionMainHelpButton()
  1201.   {
  1202.     URL url;
  1203.     try {
  1204.       url = new URL("http://" + serverHost + "/dance/java/jhelp-main" +
  1205.               ((engl) ? "-e" : "") + ".html");
  1206.     }
  1207.     catch (java.net.MalformedURLException e) {
  1208.       url = null;
  1209.     }
  1210.     getAppletContext().showDocument(url);
  1211.   }
  1212.  
  1213.   /**
  1214.    * Function will be called if the "help" button within the animation page is hit.
  1215.    * Open an URL to a help page.
  1216.    * @see Button#action
  1217.    */
  1218.   public void actionAnimationHelpButton()
  1219.   {
  1220.     URL url;
  1221.     try {
  1222.       url = new URL("http://" + serverHost + "/dance/java/jhelp-anim" +
  1223.               ((engl) ? "-e" : "") + ".html");
  1224.     }
  1225.     catch (java.net.MalformedURLException e) {
  1226.       url = null;
  1227.     }
  1228.     getAppletContext().showDocument(url);
  1229.   }
  1230.  
  1231.   /**
  1232.    * Function will be called if the "audio on | slow motion" button is hit.
  1233.    * @param on state of the toggle button.
  1234.    * @see Button#action
  1235.    */
  1236.   public void actionSoundButton(boolean on)
  1237.   {
  1238.     audioON = on;
  1239.   }
  1240.  
  1241.   /**
  1242.    * Function will be called if the "slow/quick | toe/heal" button is hit.
  1243.    * @param usehb state of the toggle button (use heal/toe).
  1244.    * @see Button#action
  1245.    * @see Figur@useComStrHT
  1246.    * @see Figur@useComStrTime
  1247.    */
  1248.   public void actionCommentButton(boolean usehb)
  1249.   {
  1250.     useCommentHT = usehb;
  1251.     if (usehb) figur.useComStrHT();
  1252.  
  1253.     else       figur.useComStrTime();
  1254.   }
  1255.  
  1256.  
  1257.  
  1258.   /**
  1259.    * Returns a String object representing.
  1260.    */
  1261.   public String toString()
  1262.   {
  1263.     return getClass().getName() + "[version=" + version + "]";
  1264.   }
  1265.  
  1266. }
  1267.  
  1268.  
  1269.  
  1270. class DebugDance
  1271. {
  1272.  
  1273.   public static void main(String args[])
  1274.   {
  1275.     Dance dance = new Dance();
  1276.     dance.init();
  1277.     dance.start();
  1278.   }
  1279. }
  1280.  
  1281.