/*
 * Chess.java
 */

package control;
import control.*;
import java.applet.Applet;
import java.applet.AudioClip;
import java.net.URL;
import java.util.List;
import javax.swing.JApplet;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

/**
 * Contains all the static methods used in Chess class.  This is a one-stop place to discover the 
 * functions that are used in the class.  These methods also wrap java functionality 
 * to make it easier for newbies to learn java.  Newbies are encouraged to look at this code to see how
 * these methods are implemented, so that they can use the java functionality without the limitations 
 * imposed here.
 *
 * @author Jeremy
 */
public class Chess {
    
    private static final String VERSION= "20070610.1";
          
    /**
     * Returns the system time in milliseconds.
     * @return number of milliseconds since midnight, Jan 1, 1970.
     */
    public static long currentTimeMillis() {
        return System.currentTimeMillis();
    }
        
    private static long lastFrameTime=0;
    
    /**
     * Pauses execution so that loops will execute at the given frame rate.
     *
     * @param framesPerSecond the number of frames per second.
     */
    public static void waitForNextFrame( double framesPerSecond ) {
        long time= System.currentTimeMillis();
        long waited=0;
        if ( lastFrameTime!=0 ) {
            int delta= (int)( 1000 / framesPerSecond );
            while ( time < ( lastFrameTime + delta ) ) {
                try { Thread.sleep(10); } catch ( InterruptedException e ) { throw new RuntimeException(e); }
                time= System.currentTimeMillis();
            }            
        }        
        lastFrameTime= time;	
    }
    
    /**
     * Pauses execution for the given number of milliseconds.
     * @param millis number of milliseconds to pause
     */
    public static void sleep( int millis ) {
        try { 
            Thread.sleep(millis); 
        } catch ( InterruptedException e ) { 
            throw new RuntimeException(e); 
        }
    }
    
        /**
     * read a string from the keyboard, presenting a dialog with the specified prompt
     * @param prompt message that is displayed to ask the user a question
     * @return the String response of the user.
     */
    public static String readString( String prompt ) {
        JOptionPane j= new JOptionPane();
        
        String result= j.showInputDialog( null, prompt, "Input Dialog", JOptionPane.DEFAULT_OPTION );
        if ( result==null ) {
            throw new RuntimeException( "Cancel was pressed.");
        }
        return result;
    }
    
    
    /**
     * read a string from the keyboard, presenting a dialog with a default prompt
     * @return the String response of the user.
     */
    public static String readString() {
        return readString("Please enter a string: ");
    }
    
    
    /**
     * read an integer from the keyboard, rereading until a valid input is given
     * @param prompt the question that is asked to the user.
     * @return the integer response of the user.
     */
    public static int readInt( String prompt ) {
        boolean notGotAnswer= true;
        int answer=-9999;
        
        while ( notGotAnswer ) {
            String result= readString( prompt );
            try {
                answer= Integer.parseInt(result);
                notGotAnswer= false;
            } catch ( NumberFormatException e ) {
                report("java couldn't read the number, just digits please");
            }
        }
        return answer;
    }
    
    /**
     * read an integer with a default prompt.
     * @return the integer response of the user.
     */
    public static int readInt() {
        return readInt( "Please enter a number: " );
    }
    
    /**
     * gets a "yes" or "no" response from the keyboard, and returns
     * the boolean true for "yes" and false for "no".
     *
     * For example:
     * <pre>
     * if ( Chess.readBoolean( "Must I say hello?" ) ) {
     *   Chess.report("Hello!");
     * }
     * </pre>
     * @param prompt the question that is asked to the user.
     * @return a boolean which is true or false.  
     */
    public static boolean readBoolean( String prompt ) {
        int i= new JOptionPane().showConfirmDialog( null, prompt, "Input Dialog", JOptionPane.YES_NO_OPTION);
        return i==0;
    }
    
    /**
     * gets a "yes" or "no" response from the keyboard.  For example:
     * <pre>
     * if ( Chess.readYesNo( "Should I say hello?" ).equals("yes") ) {
     *   Chess.report("Hello!");
     * }
     * </pre>
     * @param prompt the question that is asked to the user.
     * @return a boolean which is true or false.  
     */
    public static String readYesNo( String prompt ) {
        int i= new JOptionPane().showConfirmDialog( null, prompt, "Input Dialog", JOptionPane.YES_NO_OPTION);
        return i==0 ? "yes" : "no";        
    }
    
    /**
     * report a string to the user at the keyboard, and wait until OK is pressed.
     * @param message the message to be displayed.
     */
    public static void report( String message ) {
        new JOptionPane().showMessageDialog( null, message, "Output Dialog", JOptionPane.PLAIN_MESSAGE );
    }
        
    /**
     * report an integer to the user at the keyboard, and wait until OK is pressed.
     * @param i the integer to be displayed.
     */
    public static void report( int i ) {
        report( ""+i );
    }

    /**
     * report a float to the user at the keyboard, and wait until OK is pressed.
     * @param f the double to be displayed
     */
    public static void report( double f ) {
        report( ""+f );
    }
    
    
    /**
     * returns the number of seconds since Jan 1, 1970.
     * @return the number of seconds since midnight, January 1, 1970 
     */
    public static double getCurrentTimeSeconds() {
        return System.currentTimeMillis() / 1000.;
    }   
    
    /**
     * returns a number between 0 and max-1
     * @param max the upper bound of the range returned.  If this is 1000, then numbers in the range 0-999 are returned.
     * @return a random number between and including 0 to @param max - 1.
     *
     */
    public static int m(int max) {
        return (int)(Math.random() * max);
    }

    public static double getRan( double min, double max )
    {
        double dif = max - min;
        double ran = Math.random() * dif;
        return min + ran;
    }
    /**
     * creates a Graph within an applet.  The size of the Graph will be determined by the
     * applet, and this should be called in the applet's init() method.  Note also that the init method
     * must return before the applet is visible.  Generally a RunnableApplet is used, and the run()
     * method is the game loop.
     * @param applet the applet window that will contain the graph.  
     * @return a graph object
     */
    public static Screen newScreen( JApplet applet ) {
        Screen result= new Screen( applet.getWidth(), applet.getHeight(), applet );
        return result;
    }
    
    /**
     * creates a Graph 400 pixels wide by 300 pixels high
     * @return a graph object
     */
    public static Screen newScreen() {
        return new Screen( 400, 300, null );
    }
    
    /**
     * creates a Graph of dimension width pixels by height pixels
     * @param width width, in pixels, of the graph
     * @param height height, in pixels, of the graph
     * @return a graph object
     */
    public static Screen newScreen( int width, int height ) {
        return new Screen( width, height, null );
    }
        
    /**
     * creates a Sound object, which makes sounds.
     * @return a MusicalInstrument object
     */
    public static MusicalInstrument newMusicalInstrument( ) {
        return new MusicalInstrument();
    }
    
    /**
     * play the .wav sound file over the computer sound system, if available.
     * @param filename starts playing a .wav file and returns immediately.
     */
    public static void playSound( String filename ) {
        URL ff= Chess.findResource(filename);
        
        if ( ff==null ) {
            throw new RuntimeException( "unable to find file " + filename );
        }
        
        //AudioClip audioClip= Applet.newAudioClip( ff );
        //audioClip.play();
        Applet.newAudioClip( ff ).play();
        
    }
    
    /**
     * provides standard logic for finding a resource in our environment.  This
     * is the same as Class.getResource, except that if it is relative, then 
     * it is assumed to be in the root of the sources.
     * @param resource the resource to find, e.g. "car.gif"
     */
    final static URL findResource( String resource ) {
        if ( ! resource.startsWith("/") ) resource= "/" + resource;
        URL ff= Chess.class.getResource(resource);
        return ff;
    }
}
