// Copyright (c) 2004-2005 Sun Microsystems, Inc. All rights reserved. Use is
// subject to license terms.
// 
// This program is free software; you can redistribute it and/or modify
// it under the terms of the Lesser GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA

package org.jdesktop.jdic.screensaver;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;

/**
 * Encapsulates a screensaver in a frame.  This is a convenient way to
 * debug a screensaver without having to build a native version.  It also
 * provides a way to preview a screensaver on a platform that does not
 * currently have a native adapter provided.  To use, run ScreensaverFrame's
 * main() method with the name of the screensaver class and the parameters
 * to pass to the screensaver.
 *
 * @author  Mark Roth
 */
public class ScreensaverFrame 
    extends javax.swing.JFrame 
{
    
    /** 
     * Creates a frame to show the given screensaver.  Starts the screensaver
     * right away.
     *
     * @param screensaver The screensaver to show in this frame
     * @param params The arguments to this screensaver
     */
    public ScreensaverFrame(ScreensaverBase screensaver, String params) {
        initComponents();
        
        setSize(640, 480);
        setLocationRelativeTo(null);
        
        // Initialize and set context
        this.screensaver = screensaver;
        this.context = createContext(params);
        screensaver.baseInit(context);
        
        // Create timer to call render loop
        // XXX - Delay hard-coded to 60 FPS for now
        this.timer = new Timer(1000/60, 
            new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    ScreensaverFrame.this.screensaver.renderFrame();
                }
            });
        this.timer.start();
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
    private void initComponents() {

        setTitle("SaverBeans Screensaver Frame");
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                exitForm(evt);
            }
        });

        pack();
    }
    // </editor-fold>//GEN-END:initComponents
    
    /** Exit the Application */
    private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm
        timer.stop();
        screensaver.baseDestroy();
        dispose();
    }//GEN-LAST:event_exitForm
    
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        try {
            if(args.length == 0) usage();
            
            // Create screensaver instance 
            String screensaverClassName = args[0];
            Class screensaverClass = Class.forName(screensaverClassName);
            if(!ScreensaverBase.class.isAssignableFrom(screensaverClass)) {
                System.err.println("Error: Class " + screensaverClassName +
                    " is not a subclass of ScreensaverBase");
                System.exit(1);
            }
            ScreensaverBase screensaver = 
                (ScreensaverBase)screensaverClass.newInstance();
            
            // Collapse commandline parameters into a String:
            String params = "";
            for(int i = 1; i < args.length; i++) {
                params += args[i] + " ";
            }
            new ScreensaverFrame(screensaver, params).setVisible(true);
        }
        catch(ClassNotFoundException e) {
            System.err.println("Can't find screensaver " + e.getMessage());
        }
        catch(InstantiationException e) {
            System.err.println("Can't instantiate screensaver: " + 
                e.getMessage());
        }
        catch(IllegalAccessException e) {
            System.err.println("Can't instantiate screensaver: " + 
                e.getMessage());
        }
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables

    /** The screensaver being run in this frame */
    private ScreensaverBase screensaver;
    
    /** The screensaver context object */
    private ScreensaverContext context;
    
    /** The width of the screensaver last time we checked */
    private int prevWidth;
    /** The height of the screensaver last time we checked */
    private int prevHeight;
    
    /** Delay timer for animation */
    private Timer timer;
    
    private static void usage() {
        System.err.println("Usage: java " + ScreensaverFrame.class.getName() + 
            " <screensaverclass> [<params>]");
        System.exit(1);
    }
    
    /**
     * Creates the screensaver context object
     */
    private ScreensaverContext createContext(String params) {
        ScreensaverContext result = new ScreensaverContext();
        result.setComponent(getContentPane());
        result.getSettings().loadFromCommandline(params);
        return result;
    }
    
}
