//MyApplet.java -- @CopyLeft by tsaiwn@csie.nctu.edu.tw
// provide some good utility functions for Applets
// as long as some static utility functions for Applications
//All functions begins with "new" are for Application only
///
import java.applet.*; 
import java.awt.*;  import java.awt.image.*;
import java.io.*; import java.net.*;
import javax.swing.*;

public class MyApplet extends Applet {

   public MyApplet( ) {   // nothing to do
   }

 /// newCodeBase() --- get the user's current working Directory
   static public URL newCodeBase( ) {    // for Application
       URL codeBase = null;
       try {
          codeBase = new URL("file:" + System.getProperty("user.dir") + "/");
       } catch ( Exception e ) {
          // maybe it is an Applet, use getCodeBase() or getDocumentBase()
          try {
             //codeBase = getCodeBase( );    // for Applet
          } catch ( Exception e2) {;} // ignore
       }
       return codeBase;
   }
 /// same as newCodeBase() --- get the user's current working Directory
   static public URL getMyCodeBase( ) {    // for Application
       return newCodeBase( );
   }

 /// getAudioBoth(filename) --- get AudioClip from Application or Applet
   public AudioClip getAudioBoth(String filename) {
       AudioClip audio = null;
       try { // try Application first
          audio = newAudio(newCodeBase( ), filename);
       } catch (Exception e) { // then try Applet
       }
       if(audio == null) {   // try Applet
          try{ audio = getAudioClip(getCodeBase( ), filename);
          } catch ( Exception e ) {;}
       }
       return audio;   // send it back anyway
   } // getAudioBoth

 /// newAudio(filename) --- get AudioClip from an Application (not Applet)
   static public AudioClip newAudio(String filename) {
       AudioClip audio = null;
       try { 
          audio = newAudio(newCodeBase( ), filename);
       } catch (Exception e) { ; }
       return audio;
   } // newAudio(filename)
 /// newAudio(url, filename)
   static public AudioClip newAudio(URL base, String filename) {
       AudioClip audio = null;
       try{ audio = Applet.newAudioClip( new URL(base+ filename) );
       } catch ( Exception e ) {
          // maybe it is an Applet, you should use getAudioClip(URL url) 
          // .. or getAudioClip(URL url, String filename)  in Applet
       }
       return audio;
   } // newAudio(url, filename)
 /// newAudio(url)  --- get AudioClip from an Application (not Applet)
   static public AudioClip newAudio(URL url) {
       AudioClip audio = null;
       try{ audio = Applet.newAudioClip( url );   // JDK1.2 static method
       } catch ( Exception e ) {;}
       return audio;
   } // newAudio(url)

  /// get Image from a local file --- for Application (not Applet)
   // Note that this is a static methos
   // usage: MyApplet.newImage("your_image_filename_path");
   static public Image newImage(String filename) {
       Image image = null;
       try{
          Toolkit tkt = Toolkit.getDefaultToolkit( );
          image = tkt.getImage(filename);  //for application only
          // image = getImage(getCodeBase( ), filename); //for Applet
       } catch ( Exception e ) { image = null;}
       return image;
   } // newImage(filename)
   static public Image getMyImage(String filename) {
       return newImage(filename);
   } // getMyImage(filename)
 /// get Image from a URL
   static public Image newImage(URL url) {
       Image image = null;
       try{ Toolkit tkt = Toolkit.getDefaultToolkit( );
            image = tkt.getImage(url);  //for application only
       } catch ( Exception e ) {;}
       return image;
   } // newImage(url)

   /// @@@ 寫個 function to createMyCursor 方便使用@@@
  /// Application please uses Cursor mycsr = newMyCursor(filename);
  /// Applet please uses Cursor mycsr = createMyCursor(filename);
  ///
   /// now, this static method is for Application only
   static public java.awt.Cursor newMyCursor(String filename) throws
                                   IndexOutOfBoundsException {
       java.awt.Cursor cursor = null;
       try{
          Toolkit tkt = Toolkit.getDefaultToolkit( );
          Image csrImg = tkt.getImage(filename);  //for application
          cursor = tkt.createCustomCursor(csrImg, new Point(1,1), filename);
       } catch ( Exception e ) { // if error, give him an Hand Cursor
          cursor = new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR);
       }
       return cursor;
   } // createMyCursor

  // now, the following is for Applet, not static
   public java.awt.Cursor createMyCursor(String filename) throws
                                   IndexOutOfBoundsException {
       java.awt.Cursor cursor = null;
       try{
          Toolkit tkt = Toolkit.getDefaultToolkit( );
          //Image csrImg = tkt.getImage(filename);  //for application
          Image csrImg = getImage(getCodeBase( ), filename); //for Applet
          cursor = tkt.createCustomCursor(csrImg, new Point(1,1), filename);
       } catch ( Exception e ) {
          cursor = new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR);
       }
       return cursor;
   } // createMyCursor

  // for both Application and Applet
   static public java.awt.Cursor createMyCursor(Image image) throws
                                   IndexOutOfBoundsException {
       java.awt.Cursor cursor = null;
       try{
          Toolkit tkt = Toolkit.getDefaultToolkit( );
          cursor = tkt.createCustomCursor(image, new Point(1,1), "cursor");
       } catch ( Exception e ) {
          cursor = new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR);
       }
       return cursor;
   } // createMyCursor



   JLabel createLabelWithPicture(String filename) {
       return createLabelWithPicture(filename, "", 
                            javax.swing.SwingConstants.TRAILING);
   }
   JLabel createLabelWithPicture(String filename, String caption) {
       return createLabelWithPicture(filename, caption, 
                            javax.swing.SwingConstants.TRAILING);
   }
   JLabel createLabelWithPicture(String filename, String caption,
                                                  int alignment ) {
      JLabel ans = null;
      ImageIcon icon = null;
      try {
         Image image = myGetImageBoth(filename);
         icon = new ImageIcon( image ); 
         ans = new JLabel(caption, icon, alignment);
         ans.setVerticalTextPosition(
                            javax.swing.SwingConstants.BOTTOM);
         ans.setHorizontalTextPosition(
                            javax.swing.SwingConstants.CENTER);
      } catch (Exception e) {
         try { if(ans==null) ans = new JLabel(caption);
         } catch (Exception e2) {;}
      }
      return ans;
   }

   /// some int constants used in the following functions
     final static int TEXT_VP = javax.swing.SwingConstants.BOTTOM;
     final static int TEXT_HP = javax.swing.SwingConstants.CENTER;
     final static int IMG_V_ALIGN = javax.swing.SwingConstants.TOP;
     final static int IMG_H_ALIGN = javax.swing.SwingConstants.LEFT;
   JButton createButtonWithPicture(String filename) {
      return createButtonWithPicture(filename, "",
                 TEXT_VP, TEXT_HP, IMG_V_ALIGN, IMG_H_ALIGN );
   }
   JButton createButtonWithPicture(String filename, String caption) {
      return createButtonWithPicture(filename, caption,
                 TEXT_VP, TEXT_HP, IMG_V_ALIGN, IMG_H_ALIGN );
   }
   JButton createButtonWithPicture(String filename, String caption,
               int textVP) {
      return createButtonWithPicture(filename, caption,
                 textVP, TEXT_HP, IMG_V_ALIGN, IMG_H_ALIGN );
   }
   JButton createButtonWithPicture(String filename, String caption,
               int textVP, int textHP ) {
      return createButtonWithPicture(filename, caption,
                 textVP, textHP, IMG_V_ALIGN, IMG_H_ALIGN );
   }
   JButton createButtonWithPicture(String filename, String caption,
               int textVP, int textHP, int imgVAlign ) {
      return createButtonWithPicture(filename, caption,
                 textVP, textHP, imgVAlign, IMG_H_ALIGN );
   }
   JButton createButtonWithPicture(String filename, String caption,
               int textVP, int textHP, int imgVAlign, int imgHAlign ) {
      JButton ans = null;
      ImageIcon icon = null;
      try {
         Image image = myGetImageBoth(filename);
         icon = new ImageIcon( image ); 
         ans = new JButton(caption, icon);
           ans.setVerticalTextPosition(textVP);
           ans.setHorizontalTextPosition(textHP);
           ans.setVerticalAlignment(imgVAlign);
           ans.setHorizontalAlignment(imgHAlign);
      } catch (Exception e) {
         try { if(ans==null) ans = new JButton(caption);
         } catch (Exception e2) {;}
      }
      return ans;
   }

   Image getImageBoth(String filename) {
       return myGetImageBoth( filename);
   }
   Image myGetImageBoth(String filename) {
      Image image = null;
      try {       // Application 中讀取 Image 方法與 Applet 中不同
         image = MyApplet.newImage(filename);   //try Application first
         //println("MyApplet got image=" + image);
      } catch (Exception e) { image=null; // then, try Applet
      } // try .. catch
      if(image==null) {
         try {       // try Applet, Applet use different method
            image = getImage(new URL( getCodeBase()+ filename));
         } catch (Exception e) { image = null;}
      } //if
      try { // ok, now the last way I can try
         Toolkit tkt = Toolkit.getDefaultToolkit( );
         Class me = getClass( );   // get The class which is running
         URL url = me.getResource(filename);
         image = tkt.getImage( url ); // works for both Application+Applet
      } catch (Exception e) { image = null; } // sorry, I have no way
      return image; 
   } // myGetImageBoth

   static void runTaskManager( ) {    // Application only
       printf("Try to run the Task Manager (taskmgr ) \n" );
       try {
             try {              // 注意格式, 因字串中含有 " 雙引號 "
                Runtime.getRuntime().exec(
                  "cmd /c \"taskmgr"  + "\" " );
             } catch (Exception e95){
                // to do : how to do on Win95/98 ?
             }  // Win95/98 ?
       } catch (Exception e) {; }
   } // run taskmgr

 ///
/// some println/print utilities for MyApplet, note that this is not static
   public void println(String s) {
      try {  System.out.println(s);
      } catch (Exception e) {;} // ignore any error
   }
   public void print(String s) {     // not static
      try {  System.out.print(s);
      } catch (Exception e) {;} // ignore any error
   }
/// some printErr utilities
   public static void printErr(String s) {
      try {  System.out.println(s);
      } catch (Exception e) {;} // ignore any error
   }
   public static void printf(String s) {
      try {  System.out.print(s);
      } catch (Exception e) {;} // ignore any error
   }
   public static void printf(long n) throws IOException {
      System.out.print(""+n);
   }
   public static void printf(int n) throws IOException {
      System.out.print(""+n);
   }
  /// print n as w columns width
   public static void printf(short n, int w) {
      printf((long)n, w);   // print n as w columns
   }
   public static void printf(int n, int w) {
      printf((long)n, w);
   }
   public static void printf(long n, int w) {
      long tmp = 1;   // print n as w columns
      long nabs = n; if(n<0) {nabs = -nabs; --w; }  // ensure positive
      for(;;) {
          tmp *= 10;
          if(tmp > nabs) break;
          --w;    // w is the expected Width (number of digits)
      }
      try {
         for(;;) {
             if(--w <= 0) break;
             System.out.print(" ");   // necessary leading space
         }
         System.out.print(""+n);
      } catch (Exception e) {;} // ignore any error
   }

   public void flush( ) {
      try { System.out.flush( );
      } catch (Exception e) {;} // ignore any error
   }

   static public void fflush( ) {
      try { System.out.flush( );
      } catch (Exception e) {;} // ignore any error
   }

  /// a main program to test my printf functions
   public static void main(String[]p) throws IOException {
       printf("=="); printf(1, 1); printf("==\n");
       printf("=="); printf(2, 2); printf("==\n");
       printf("=="); printf(3, 3); printf("==\n");
       printf("=="); printf(11, 1); printf("==\n");
       printf("=="); printf(12, 2); printf("==\n");
       printf("=="); printf(13, 3); printf("==\n");
       printf("=="); printf(111, 1); printf("==\n");
       printf("=="); printf(112, 2); printf("==\n");
       printf("=="); printf(113, 3); printf("==\n");
       printf("=="); printf(114, 4); printf("==\n");
       printf("=="); printf(115, 5); printf("==\n");
       printf("=="); printf(-11, 1); printf("==\n");
       printf("=="); printf(-12, 2); printf("==\n");
       printf("=="); printf(-13, 3); printf("==\n");
       printf("=="); printf(-14, 4); printf("==\n");
       printf("=="); printf(-15, 5); printf("==\n");
       printf("=="); printf(-116, 6); printf("==\n");
       try {
          AudioClip sound = null; sound = newAudio("laugh.au");
          if(sound != null) { sound.play( ); Thread.sleep(2588); }
       } catch(Exception e) {;}
       printf("Thank you!\n");  System.exit(0);
   }
} // class MyApplet

class PicturePanel extends MyApplet implements ImageObserver {
   String filename = null;
   String caption = null;
   Image image = null;
   public PicturePanel(String filename) {
      this(filename, "");   // call other Constructor
   }
   public PicturePanel(String filename, String caption) {
      this.filename = filename;
      this.caption = caption;
      try {
         Toolkit tkt = Toolkit.getDefaultToolkit( );
         Class me = getClass( );   // get The class is running
         URL url = me.getResource(filename);
         image = tkt.getImage( url ); // works for both Application+Applet
      } catch (Exception e) { ; }
      repaint( );
   }
   public void update(Graphics g) {
       paint(g);   // call paint directly without clear the panel
   }
   public void paint(Graphics g) {
      int xpos = 12, ypos = 12;
      if(image!=null) {
         g.drawImage(image, 2, 2, this );     // Align left-upper corner
         try {
            xpos = image.getWidth(this)/4;
            ypos = image.getHeight(this) - 24;
         }catch(Exception e) {;}
      }
      if(caption != null) {
          g.setFont(new Font("細明體", Font.PLAIN, 18) );
          g.setColor(Color.red);
          g.drawString( caption, xpos, ypos );
      }
   } // paint
} // PicturePanel
