//******************************************************************************
// avemaria.java:  Applet
//
//******************************************************************************
import java.applet.*;
import java.awt.*;

//==============================================================================
// Main Class for applet avemaria
//
//==============================================================================
public class avemaria extends Applet implements Runnable
{
  // THREAD SUPPORT:
  //    avm_avemaria  is the Thread object for the applet
  //--------------------------------------------------------------------------
  Thread   avm_avemaria = null;

  // ANIMATION SUPPORT:
  //    avm_Graphics    used for storing the applet's Graphics context
  //    avm_Images[]    the array of Image objects for the animation
  //    avm_nCurrImage  the index of the next image to be displayed
  //    avm_ImgWidth    width of each image
  //    avm_ImgHeight    height of each image
  //    avm_fAllLoaded  indicates whether all images have been loaded
  //    NUM_IMAGES     number of images used in the animation
  //--------------------------------------------------------------------------

  private Graphics avm_Graphics;
  private Image   avm_Images[];
  private int    avm_nCurrImage, x, y, z, w, v;
  private int    avm_nImgWidth  = 0;
  private int    avm_nImgHeight = 0;
  private boolean  avm_fAllLoaded = false;
  private final int NUM_IMAGES = 11;

  // STANDALONE APPLICATION SUPPORT:
  //    avm_fStandAlone will be set to true if applet is run standalone
  //--------------------------------------------------------------------------
  boolean avm_fStandAlone = false;

  // PARAMETER SUPPORT:
  //    Parameters allow an HTML author to pass information to the applet;
  // the HTML author specifies them using the <PARAM> tag within the <APPLET>
  // tag.  The following variables are used to store the values of the
  // parameters.
  //--------------------------------------------------------------------------

  // Members for applet parameters
  // <type>       <MemberVar>    = <Default Value>
  //--------------------------------------------------------------------------
  private String avm_Nombre = "Ave Marķa";
  private int avm_NumeroDeImagenes = 11;
  private double avm_Doble = 0.0;
  private float avm_Flotante = 0.0f;
  private boolean avm_Buleano = true;
  private long avm_Largo = 0;

  // Parameter names.  To change a name of a parameter, you need only make
  // a single change.  Simply modify the value of the parameter string below.
  //--------------------------------------------------------------------------
  private final String PARAM_Nombre = "Nombre";
  private final String PARAM_NumeroDeImagenes = "NumeroDeImagenes";
  private final String PARAM_Doble = "Doble";
  private final String PARAM_Flotante = "Flotante";
  private final String PARAM_Buleano = "Buleano";
  private final String PARAM_Largo = "Largo";

  // STANDALONE APPLICATION SUPPORT
  //   The GetParameter() method is a replacement for the getParameter() method
  // defined by Applet. This method returns the value of the specified parameter;
  // unlike the original getParameter() method, this method works when the applet
  // is run as a standalone application, as well as when run within an HTML page.
  // This method is called by GetParameters().
  //---------------------------------------------------------------------------
  String GetParameter(String strName, String args[])
  {
    if (args == null)
    {
      // Running within an HTML page, so call original getParameter().
      //-------------------------------------------------------------------
      return getParameter(strName);
    }

    // Running as standalone application, so parameter values are obtained from
    // the command line. The user specifies them as follows:
    //
    //  Java.exe avemaria param1=<val> param2=<"val with spaces"> ...
    //-----------------------------------------------------------------------
    int    i;
    String strArg  = strName + "=";
    String strValue = null;

    for (i = 0; i < args.length; i++)
    {
      if (strArg.equalsIgnoreCase(args[i].substring(0, strArg.length())))
      {
        // Found matching parameter on command line, so extract its value.
        // If in double quotes, remove the quotes.
        //---------------------------------------------------------------
        strValue= args[i].substring(strArg.length());
        if (strValue.startsWith("\""))
        {
          strValue = strValue.substring(1);
          if (strValue.endsWith("\""))
            strValue = strValue.substring(0, strValue.length() - 1);
        }
      }
    }

    return strValue;
  }

  // STANDALONE APPLICATION SUPPORT
  //   The GetParameters() method retrieves the values of each of the applet's
  // parameters and stores them in variables. This method works both when the
  // applet is run as a standalone application and when it's run within an HTML
  // page.  When the applet is run as a standalone application, this method is
  // called by the main() method, which passes it the command-line arguments.
  // When the applet is run within an HTML page, this method is called by the
  // init() method with args == null.
  //---------------------------------------------------------------------------
  void GetParameters(String args[])
  {
    // Query values of all Parameters
    //--------------------------------------------------------------
    String param;

    // Nombre: Nombre de la ventana
    //--------------------------------------------------------------
    param = GetParameter(PARAM_Nombre, args);
    if (param != null)
      avm_Nombre = param;

    // NumeroDeImagenes: Numero de Imagenes
    //--------------------------------------------------------------
    param = GetParameter(PARAM_NumeroDeImagenes, args);
    if (param != null)
      avm_NumeroDeImagenes = Integer.parseInt(param);

    // Doble: Doble
    //--------------------------------------------------------------
    param = GetParameter(PARAM_Doble, args);
    if (param != null)
      avm_Doble = Double.valueOf(param).doubleValue();

    // Flotante: Flotante
    //--------------------------------------------------------------
    param = GetParameter(PARAM_Flotante, args);
    if (param != null)
      avm_Flotante = Float.valueOf(param).floatValue();

    // Buleano: Buleano
    //--------------------------------------------------------------
    param = GetParameter(PARAM_Buleano, args);
    if (param != null)
      avm_Buleano = Boolean.valueOf(param).booleanValue();

    // Largo: Largo
    //--------------------------------------------------------------
    param = GetParameter(PARAM_Largo, args);
    if (param != null)
      avm_Largo = Long.parseLong(param);

  }

  // STANDALONE APPLICATION SUPPORT
  //   The main() method acts as the applet's entry point when it is run
  // as a standalone application. It is ignored if the applet is run from
  // within an HTML page.
  //--------------------------------------------------------------------------
  public static void main(String args[])
  {
    // Create Toplevel Window to contain applet avemaria
    //----------------------------------------------------------------------
    avemariaframe frame = new avemariaframe("avemaria");

    // Must show Frame before we size it so insets() will return valid values
    //----------------------------------------------------------------------
    frame.show();
    frame.hide();
    frame.resize(frame.insets().left + frame.insets().right  + 640,
    frame.insets().top  + frame.insets().bottom + 480);

    // The following code starts the applet running within the frame window.
    // It also calls GetParameters() to retrieve parameter values from the
    // command line, and sets avm_fStandAlone to true to prevent init() from
    // trying to get them from the HTML page.
    //----------------------------------------------------------------------
    avemaria applet_avemaria = new avemaria();

    frame.add("Center", applet_avemaria);
    applet_avemaria.avm_fStandAlone = true;
    applet_avemaria.GetParameters(args);
    applet_avemaria.init();
    applet_avemaria.start();
    frame.show();
  }

  // avemaria Class Constructor
  //--------------------------------------------------------------------------
  public avemaria()
  {
    // Add constructor code here
  }

  // APPLET INFO SUPPORT:
  //    The getAppletInfo() method returns a string describing the applet's
  // author, copyright date, or miscellaneous information.
  //--------------------------------------------------------------------------
  public String getAppletInfo()
  {
    return "Ave Maria program. Rafael Jardon <rjm@arrakis.es>";
  }

  // PARAMETER SUPPORT
  //    The getParameterInfo() method returns an array of strings describing
  // the parameters understood by this applet.
  //
  // avemaria Parameter Information:
  //  { "Name", "Type", "Description" },
  //--------------------------------------------------------------------------
  public String[][] getParameterInfo()
  {
    String[][] info =
    {
      { PARAM_Nombre, "String", "Nombre de la ventana" },
      { PARAM_NumeroDeImagenes, "int", "Numero de Imagenes" },
      { PARAM_Doble, "double", "Doble" },
      { PARAM_Flotante, "float", "Flotante" },
      { PARAM_Buleano, "boolean", "Buleano" },
      { PARAM_Largo, "long", "Largo" },
    };
    return info;    
  }

  // The init() method is called by the AWT when an applet is first loaded or
  // reloaded.  Override this method to perform whatever initialization your
  // applet needs, such as initializing data structures, loading images or
  // fonts, creating frame windows, setting the layout manager, or adding UI
  // components.
  //--------------------------------------------------------------------------
  public void init()
  {
    if (!avm_fStandAlone)
      GetParameters(null);
        // If you use a ResourceWizard-generated "control creator" class to
        // arrange controls in your applet, you may want to call its
        // CreateControls() method from within this method. Remove the following
        // call to resize() before adding the call to CreateControls();
        // CreateControls() does its own resizing.
        //----------------------------------------------------------------------
    
     resize(640, 480);
     
     //  Place additional initialization code here
  }

  // Place additional applet clean up code here.  destroy() is called when
  // when you applet is terminating and being unloaded.
  //-------------------------------------------------------------------------
  public void destroy()
  {
    //  Place applet cleanup code here
  }

  // ANIMATION SUPPORT
  //    The imageUpdate() method is called repeatedly by the AWT while
  // images are being constructed.  The flags parameter provides information
  // about the status of images under construction.  The initial implementation
  // of this method checks whether the ALLBITS flag is set.
  // When the ALLBITS is set, this method knows that an image is
  // completely loaded. When all the images are completely loaded, this
  // method sets the avm_fAllLoaded variable to true so that animation can begin.
  //--------------------------------------------------------------------------
  public void update(Graphics g)
  {
  paint(g);
  }

  public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h)
  {
    
    // Nothing to do if images are all loaded
    //----------------------------------------------------------------------
    if (avm_fAllLoaded)
    return false;

    // Want all bits to be available before painting
    //----------------------------------------------------------------------
    if ((flags & ALLBITS) == 0)
    return true;

    // All bits are available, so increment loaded count of fully
    // loaded images, starting animation if all images are loaded
    //----------------------------------------------------------------------
    if (++avm_nCurrImage == NUM_IMAGES)
    {
      avm_nCurrImage = 0;
      avm_fAllLoaded = true;
    }        

    return false;
  }

  // ANIMATION SUPPORT:
  //    Draws the next image, if all images are currently loaded
  //--------------------------------------------------------------------------

  private void displayImage(Graphics g)
  {
    if (!avm_fAllLoaded)
    return;

    // Draw Image in center of applet
    //----------------------------------------------------------------------

    String madre="Madre de todos los pueblos";
    String ave="Madre de Dios y Madre nuestra";
    String avm_Madre;
    String avm_AveMaria;

    if(avm_nCurrImage==0)
    {
      x=y=z=v=w=0;
      g.setColor(Color.black);
      g.fillRect(0,0,640,480);

      g.drawImage(avm_Images[0], 210,50,null);
      
      // g.drawImage(avm_Images[avm_nCurrImage], (size().width - avm_nImgWidth)   / 2 + 3,
      //   (size().height - avm_nImgHeight) / 2 , null);
    }
    else
    {
      g.drawImage(avm_Images[avm_nCurrImage], x, y,null);
      g.drawImage(avm_Images[avm_nCurrImage], 550 + z, y,null);
    
      g.setColor(Color.green);
      g.setFont(new Font("TimesRoman", Font.BOLD, 38));
      avm_Madre=madre.substring(0,w+1);
      g.drawString(avm_Madre, 100,40);
      
      g.setColor(Color.yellow);
      avm_AveMaria=ave.substring(0,v+1);
      g.drawString(avm_AveMaria, 60,440);
      
      x+=10; y+=36; z-=10; w+=3; v+=4;
      if(w > madre.length()) w=madre.length()-1;
      if(v > ave.length()) v=ave.length()-1;
    } 
  }

  // avemaria Paint Handler
  //--------------------------------------------------------------------------
  public void paint(Graphics g)
  {
    // ANIMATION SUPPORT:
    //    The following code displays a status message until all the
    // images are loaded. Then it calls displayImage to display the current
    // image.
    //----------------------------------------------------------------------
    
    if (avm_fAllLoaded)
    {
      // Rectangle r = g.getClipRect();
      // g.clearRect(r.x, r.y, r.width, r.height);

      g.setColor(Color.black);
      g.fillRect(0,0,640,480);
     
      displayImage(g);
    }
    else
    {
      g.drawString("Loading images...", 10, 20);
      avm_fAllLoaded=true;
    }

    //  Place additional applet Paint code here
  }

  //    The start() method is called when the page containing the applet
  // first appears on the screen. The initial implementation
  // of this method starts execution of the applet's thread.
  //--------------------------------------------------------------------------
  public void start()
  {
    if (avm_avemaria == null)
    {
      avm_avemaria = new Thread(this);
      avm_avemaria.start();
    }
    //  Place additional applet start code here
  }
  
  //    The stop() method is called when the page containing the applet is
  // no longer on the screen. The initial implementation of
  // this method stops execution of the applet's thread.
  //--------------------------------------------------------------------------
  public void stop()
  {
    if (avm_avemaria != null)
    {
      avm_avemaria.stop();
      avm_avemaria = null;
    }

    //  Place additional applet stop code here
  }

  // THREAD SUPPORT
  //    The run() method is called when the applet's thread is started. If
  // your applet performs any ongoing activities without waiting for user
  // input, the code for implementing that behavior typically goes here. For
  // example, for an applet that performs animation, the run() method controls
  // the display of images.
  //--------------------------------------------------------------------------
  public void run()
  {
    repaint();

    avm_Graphics = getGraphics();
    avm_nCurrImage   = 0;
    avm_Images   = new Image[NUM_IMAGES];
    
    // Load in all the images
    //----------------------------------------------------------------------
    String strImage;

    // For each image in the animation, this method first constructs a
    // string containing the path to the image file; then it begins loading
    // the image into the avm_Images array.  Note that the call to getImage
    // will return before the image is completely loaded.
    //----------------------------------------------------------------------
    for (int i = 1; i <= NUM_IMAGES; i++)
    {
      // Build path to next image
      //------------------------------------------------------------------
      
      if(i==1) strImage="madetolp.jpg" ;
      else strImage = "tierra" + ((i < 10) ? "0" : "") + i + ".gif";

      if (avm_fStandAlone)
        avm_Images[i-1] = Toolkit.getDefaultToolkit().getImage(strImage);
      else
        avm_Images[i-1] = getImage(getDocumentBase(), strImage);

      // Get width and height of one image.
      // Assuming all images are same width and height
      //------------------------------------------------------------------

      if(avm_nImgWidth == 0 && i > 1)
      {
        try
        {
          // The getWidth() and getHeight() methods of the Image class
          // return -1 if the dimensions are not yet known. The
          // following code keeps calling getWidth() and getHeight()
          // until they return actual values.
          // NOTE: This is only executed once in this loop, since we
          //       are assuming all images are the same width and
          //       height.  However, since we do not want to duplicate
          //       the above image load code, the code resides in the
          //       loop.
          //----------------------------------------------------------
          while ((avm_nImgWidth = avm_Images[i-1].getWidth(null)) < 0)
          Thread.sleep(1);

          while ((avm_nImgHeight = avm_Images[i-1].getHeight(null)) < 0)
            Thread.sleep(1);
         }
        catch (InterruptedException e)
        {
          //       Place exception-handling code here in case an
          //       InterruptedException is thrown by Thread.sleep(),
          //     meaning that another thread has interrupted this one
        }
      }

      // Force image to fully load
      //------------------------------------------------------------------

      avm_Graphics.drawImage(avm_Images[i-1], -1000, -1000,this);
    }

    // Wait until all images are fully loaded
    //----------------------------------------------------------------------
   
    while(!avm_fAllLoaded)
    {
      try
      {
        Thread.sleep(10);
      }
      catch (InterruptedException e)
      {
        //       Place exception-handling code here in case an
        //       InterruptedException is thrown by Thread.sleep(),
        //     meaning that another thread has interrupted this one
      }
    }

    repaint();

    while (true)
    {
      try
      {
        // Draw next image in animation
        //--------------------------------------------------------------
        displayImage(avm_Graphics);
        avm_nCurrImage++;
        if (avm_nCurrImage == NUM_IMAGES)
        {
          avm_nCurrImage =0;
          Thread.sleep(3000); 
        }

        //  Add additional thread-specific code here
        Thread.sleep(100);
      }
      catch (InterruptedException e)
      {
        //       Place exception-handling code here in case an
        //       InterruptedException is thrown by Thread.sleep(),
        //     meaning that another thread has interrupted this one
        stop();
      }
    }
  }

  // MOUSE SUPPORT:
  //    The mouseDown() method is called if the mouse button is pressed
  // while the mouse cursor is over the applet's portion of the screen.
  //--------------------------------------------------------------------------
  public boolean mouseDown(Event evt, int x, int y)
  {
    //  Place applet mouseDown code here
    stop();
    return true;
  }

  // MOUSE SUPPORT:
  //    The mouseUp() method is called if the mouse button is released
  // while the mouse cursor is over the applet's portion of the screen.
  //--------------------------------------------------------------------------
  public boolean mouseUp(Event evt, int x, int y)
  {
    //  Place applet mouseUp code here
    start(); 
    return true;
  }

  // MOUSE SUPPORT:
  //    The mouseDrag() method is called if the mouse cursor moves over the
  // applet's portion of the screen while the mouse button is being held down.
  //--------------------------------------------------------------------------
  public boolean mouseDrag(Event evt, int x, int y)
  {
    //  Place applet mouseDrag code here
    return true;
  }

  // MOUSE SUPPORT:
  //    The mouseMove() method is called if the mouse cursor moves over the
  // applet's portion of the screen and the mouse button isn't being held down.
  //--------------------------------------------------------------------------
  public boolean mouseMove(Event evt, int x, int y)
  {
    //  Place applet mouseMove code here
    return true;
  }

  // MOUSE SUPPORT:
  //    The mouseEnter() method is called if the mouse cursor enters the
  // applet's portion of the screen.
  //--------------------------------------------------------------------------
  public boolean mouseEnter(Event evt, int x, int y)
  {
    //  Place applet mouseEnter code here
    return true;
  }

  // MOUSE SUPPORT:
  //    The mouseExit() method is called if the mouse cursor leaves the
  // applet's portion of the screen.
   //--------------------------------------------------------------------------
  public boolean mouseExit(Event evt, int x, int y)
  {
    //  Place applet mouseExit code here
    return true;
  }

  //  Place additional applet code here

}

//==============================================================================
// STANDALONE APPLICATION SUPPORT
//   This frame class acts as a top-level window in which the applet appears
// when it's run as a standalone application.
//==============================================================================

class avemariaframe extends Frame
{
  // avemariaframe constructor
  //--------------------------------------------------------------------------
  public avemariaframe(String str)
  {
    //  Add additional construction code here
    super (str);
  }

  // The handleEvent() method receives all events generated within the frame
  // window. You can use this method to respond to window events. To respond
  // to events generated by menus, buttons, etc. or other controls in the
  // frame window but not managed by the applet, override the window's
  // action() method.
  //--------------------------------------------------------------------------
  public boolean handleEvent(Event evt)
  {
    switch (evt.id)
    {
      // Application shutdown (e.g. user chooses Close from the system menu).
      //------------------------------------------------------------------
      case Event.WINDOW_DESTROY:
        //  Place additional clean up code here
        dispose();
        System.exit(0);
        return true;

      default:
        return super.handleEvent(evt);
    }       
  }
}
