// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.geocities.com/kpdus/jad.html
// Decompiler options: packimports(3) 
// Source File Name:   GifGolf.java

/*
  <applet code="GifGolf.class" codebase="."
        width="500" height="460">
        </applet>
*/

import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.PrintStream;
import java.net.URL;
import java.util.Hashtable;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class GifGolf extends JApplet
    implements ActionListener, MouseListener, ChangeListener
{
    class CoursePanel extends JPanel
    {

        public void scorecard()
        {
            scoring = true;
            repaint();
        }

        public boolean scoring()
        {
            return scoring;
        }

        public boolean intro()
        {
            return instruct > 0;
        }

        public void newHole(String s)
        {
            if(instruct == 1)
            {
                s = "intro2.gif";
                instruct = 2;
            } else
            if(instruct == 2)
                instruct = 0;
            try
            {
                hole = ImageIO.read(new File(s));
            }
            catch(IOException ioexception)
            {
                System.err.println(ioexception.getMessage());
                ioexception.printStackTrace();
            }
            if(instruct > 0)
                return;
            ballLoc = new java.awt.geom.Point2D.Double(0.0D, 0.0D);
            int i = 0;
            int j = 0;
            holeLoc = new Point(0, 0);
            for(int k = 0; k < 400; k++)
            {
                for(int l = 0; l < 400; l++)
                {
                    if(hole.getRGB(k, l) == 0xffff0000)
                    {
                        ballLoc.setLocation(ballLoc.x + (double)k, ballLoc.y + (double)l);
                        i++;
                    }
                    if(hole.getRGB(k, l) == 0xff000000)
                    {
                        holeLoc.setLocation(holeLoc.x + k, holeLoc.y + l);
                        j++;
                    }
                }

            }

            ballLoc.setLocation(ballLoc.x / (double)i, ballLoc.y / (double)i);
            holeLoc.setLocation(holeLoc.x / j, holeLoc.y / j);
            setYlabel();
            backLoc = null;
            onTee = true;
            wasOnTee = true;
            scoring = false;
            repaint();
        }

        public void onGreen()
        {
            gx = 0;
            gy = 0;
            int i = 0;
            for(int j = 0; j < 400; j++)
            {
                for(int l = 0; l < 400; l++)
                {
                    if(hole.getRGB(j, l) == 0xff00ff00)
                    {
                        gx += j;
                        gy += l;
                        i++;
                    }
                    if(hole.getRGB(j, l) == 0xff000000)
                        hole.setRGB(j, l, 0xff00ff00);
                }

            }

            gx /= i;
            gy /= i;
            int k = (holeLoc.x - gx) * 10 + 200;
            int i1 = (holeLoc.y - gy) * 10 + 200;
            double d = (ballLoc.x - (double)gx) * 10D + 200D;
            double d1 = (ballLoc.y - (double)gy) * 10D + 200D;
            holeLoc = new Point(k, i1);
            ballLoc = new java.awt.geom.Point2D.Double(d, d1);
            BufferedImage bufferedimage = hole.getSubimage(gx - 20, gy - 20, 40, 40);
            hole = bufferedimage;
            setYlabel();
            repaint();
        }

        private void setYlabel()
        {
            double d = ballLoc.distance(holeLoc);
            if(GifGolf.this.onGreen)
                d = (d * 3D) / 10D;
            ylabel.setText((new Integer((int)d)).toString());
        }

        public void setBack(int i, int j)
        {
            backLoc = new Point(i, j);
        }

        public java.awt.geom.Point2D.Double where()
        {
            return ballLoc;
        }

        public boolean oob()
        {
            return oob;
        }

        public void reload()
        {
            ballLoc = lastBall;
            oob = false;
            if(wasOnTee)
                onTee = true;
            setYlabel();
            repaint();
        }

        public int terrain()
        {
            if(onTee)
                return 1;
            if(oob)
                return -1;
            int i;
            if(GifGolf.this.onGreen)
                i = hole.getRGB((int)(ballLoc.x / 10D), (int)(ballLoc.y / 10D));
            else
                i = hole.getRGB((int)ballLoc.x, (int)ballLoc.y);
            switch(i)
            {
            case -16777216: 
            case -16711936: 
                return 0;

            case -16727040: 
            case -65536: 
                return 1;

            case -16753152: 
            case -1: 
                return 2;

            case -3826855: 
                return 3;

            case -8224001: 
                return 4;
            }
            return 2;
        }

        public void moveBall(double d, double d1, double d2)
        {
            if(backLoc != null)
            {
                lastBall = (java.awt.geom.Point2D.Double)(java.awt.geom.Point2D.Double)ballLoc.clone();
                travelVec = new java.awt.geom.Point2D.Double(ballLoc.x - (double)backLoc.x, ballLoc.y - (double)backLoc.y);
                double d3 = ballLoc.distance(backLoc);
                travelVec.x /= d3;
                travelVec.y /= d3;
                backLoc = null;
                if(!onTee)
                    wasOnTee = false;
                onTee = false;
            }
            double d4 = d * travelVec.x - d1 * travelVec.y;
            double d5 = d * travelVec.y + d1 * travelVec.x;
            ballLoc.x += d4;
            ballLoc.y += d5;
            if(ballLoc.x < 5D || ballLoc.x >= 395D || ballLoc.y < 5D || ballLoc.y >= 395D)
                oob = true;
            if(GifGolf.this.onGreen && ballLoc.distance(holeLoc) < 4D && d2 < 18D)
            {
                ballLoc.x = holeLoc.x;
                ballLoc.y = holeLoc.y;
                inHole = true;
            }
            setYlabel();
        }

        public void paintComponent(Graphics g)
        {
            Graphics2D graphics2d = (Graphics2D)g;
            if(instruct > 0)
                graphics2d.drawImage(hole, 0, 0, 400, 400, null);
            else
            if(scoring)
            {
                graphics2d.setColor(Color.GREEN);
                graphics2d.fill(new Rectangle(0, 0, 400, 400));
                graphics2d.setColor(Color.BLACK);
                int i = 0;
                int j = 0;
                byte byte0 = 52;
                graphics2d.draw(new java.awt.geom.Line2D.Double(7D, 97 + byte0, 365D, 97 + byte0));
                graphics2d.drawString("Hole", 15, 110 + byte0);
                graphics2d.draw(new java.awt.geom.Line2D.Double(7D, 117 + byte0, 365D, 117 + byte0));
                graphics2d.drawString("Hcp", 15, 130 + byte0);
                graphics2d.draw(new java.awt.geom.Line2D.Double(7D, 137 + byte0, 365D, 137 + byte0));
                graphics2d.drawString("Par", 15, 150 + byte0);
                graphics2d.draw(new java.awt.geom.Line2D.Double(7D, 157 + byte0, 365D, 157 + byte0));
                graphics2d.drawString("Score", 15, 170 + byte0);
                graphics2d.draw(new java.awt.geom.Line2D.Double(7D, 97 + byte0, 7D, 177 + byte0));
                int k = 0;
                int l = 0;
                for(int i1 = 0; i1 < 9; i1++)
                {
                    graphics2d.draw(new java.awt.geom.Line2D.Double(i1 * 30 + 52, 97 + byte0, i1 * 30 + 52, 177 + byte0));
                    graphics2d.drawString((new Integer(i1 + 1 + 9 * j)).toString(), i1 * 30 + 60, 110 + byte0);
                    k += PAR[course][i1 + 9 * j];
                    graphics2d.drawString((new Integer(PAR[course][i1 + 9 * j])).toString(), i1 * 30 + 60, 150 + byte0);
                    graphics2d.drawString((new Integer(HCP[course][i1 + 9 * j])).toString(), i1 * 30 + 60, 130 + byte0);
                    l += strokes[i1];
                    graphics2d.drawString((new Integer(strokes[i1 + 9 * j])).toString(), i1 * 30 + 60, 170 + byte0);
                }

                i += k;
                graphics2d.draw(new java.awt.geom.Line2D.Double(322D, 97 + byte0, 322D, 177 + byte0));
                graphics2d.draw(new java.awt.geom.Line2D.Double(365D, 97 + byte0, 365D, 177 + byte0));
                graphics2d.drawString("Total", 330, 110 + byte0);
                graphics2d.drawString((new Integer(k)).toString(), 330, 150 + byte0);
                graphics2d.drawString((new Integer(l)).toString(), 330, 170 + byte0);
                graphics2d.draw(new java.awt.geom.Line2D.Double(7D, 177 + byte0, 365D, 177 + byte0));
                if(course == 0)
                {
                    graphics2d.setColor(Color.WHITE);
                    graphics2d.fill(new Rectangle(300, 350, 100, 50));
                    graphics2d.setColor(Color.BLACK);
                    if(total <= 40)
                    {
                        graphics2d.drawString("Continue", 325, 375);
                        graphics2d.drawString("You made the cut!", 150, 375);
                    } else
                    {
                        graphics2d.drawString("Try again", 325, 375);
                        graphics2d.drawString("You missed the cut", 150, 375);
                    }
                }
            } else
            {
                graphics2d.drawImage(hole, 0, 0, 400, 400, null);
                graphics2d.setColor(Color.WHITE);
                graphics2d.fill(new java.awt.geom.Ellipse2D.Float((int)(ballLoc.x - 1.0D), (int)(ballLoc.y - 1.0D), 3F, 3F));
                graphics2d.setColor(Color.RED);
                if(backLoc != null)
                    graphics2d.drawLine(backLoc.x, backLoc.y, (int)ballLoc.x, (int)ballLoc.y);
                if(GifGolf.this.onGreen)
                {
                    graphics2d.setColor(Color.BLACK);
                    graphics2d.fill(new java.awt.geom.Ellipse2D.Float(holeLoc.x - 2, holeLoc.y - 2, 5F, 5F));
                }
            }
        }

        private JLabel ylabel;
        private BufferedImage hole;
        private Point backLoc;
        private Point holeLoc;
        private boolean onTee;
        private boolean wasOnTee;
        private boolean oob;
        private java.awt.geom.Point2D.Double ballLoc;
        private java.awt.geom.Point2D.Double travelVec;
        private java.awt.geom.Point2D.Double lastBall;
        private final int TEECOLOR = 0xffff0000;
        private final int ROUGH = 0xff005e00;
        private final int FAIRWAY = 0xff00c400;
        private final int GREEN = 0xff00ff00;
        private final int WATER = 0xff8282ff;
        private final int SAND = 0xffc59b59;
        private final int HOLE = 0xff000000;
        private final int WORDS = -1;
        private int gx;
        private int gy;
        private boolean scoring;
        private int instruct;

        public CoursePanel(JLabel jlabel)
        {
            super();
            scoring = false;
            instruct = 1;
            try
            {
                hole = ImageIO.read(new URL(getCodeBase(), "intro.gif"));
            }
            catch(IOException ioexception)
            {
                System.err.println(ioexception.getMessage());
                ioexception.printStackTrace();
            }
            setPreferredSize(new Dimension(400, 400));
            ylabel = jlabel;
        }
    }

    public class PowerPanel extends JPanel
    {

        public void incr()
        {
            barh++;
            if(barh == 210)
                barh = 10;
        }

        public void ticktock()
        {
            barx += dbarx;
            if(barx == 90)
                dbarx = -1;
            if(barx == 10)
                dbarx = 1;
        }

        public void reset()
        {
            barh = 10;
            barx = 50;
        }

        public double getPPct()
        {
            return (double)(barh - 10) / 200D;
        }

        public double getSPct()
        {
            return (double)(barx - 40) / 200D;
        }

        public void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            Graphics2D graphics2d = (Graphics2D)g;
            graphics2d.setColor(Color.BLACK);
            graphics2d.fill(new Rectangle(49, 10, 3, 200));
            graphics2d.fill(new Rectangle(10, 220 - barh - 1, 80, 3));
            graphics2d.setColor(Color.WHITE);
            graphics2d.fill(new Rectangle(barx - 3, 220 - barh - 3, 7, 7));
        }

        private int barh;
        private int barx;
        private int dbarx;

        public PowerPanel()
        {
            super();
            setPreferredSize(new Dimension(100, 220));
            setBackground(Color.GREEN);
            barh = 10;
            barx = 50;
            dbarx = 1;
        }
    }


    public GifGolf()
    {
        upSwing = false;
        downSwing = false;
        inFlight = false;
        onGreen = false;
        inHole = false;
        powerPanel = null;
    }

    public void makeGolf()
    {
        JPanel jpanel = new JPanel();
        jpanel.setLayout(new BorderLayout());
        JPanel jpanel1 = new JPanel();
        jpanel1.setLayout(new GridLayout(4, 2));
        jpanel1.add(new JLabel("Hole"));
        hlabel = new JLabel("1");
        jpanel1.add(hlabel);
        jpanel1.add(new JLabel("Par"));
        plabel = new JLabel("4");
        jpanel1.add(plabel);
        ulabel = new JLabel("Yards");
        jpanel1.add(ulabel);
        ylabel = new JLabel();
        jpanel1.add(ylabel);
        jpanel1.add(new JLabel("Score"));
        slabel = new JLabel("0");
        jpanel1.add(slabel);
        jpanel.add(jpanel1, "North");
        powerPanel = new PowerPanel();
        jpanel.add(powerPanel);
        sb = new JButton("Swing");
        sb.addActionListener(this);
        sb.setEnabled(false);
        jpanel.add(sb, "South");
        getContentPane().add(jpanel, "East");
        theHole = new CoursePanel(ylabel);
        theHole.addMouseListener(this);
        getContentPane().add(theHole);
        clubsl = new JSlider(0, 10, 0);
        Hashtable hashtable = new Hashtable();
        hashtable.put(new Integer(0), new JLabel("1W"));
        hashtable.put(new Integer(1), new JLabel("3W"));
        hashtable.put(new Integer(2), new JLabel("3I"));
        hashtable.put(new Integer(3), new JLabel("4I"));
        hashtable.put(new Integer(4), new JLabel("5I"));
        hashtable.put(new Integer(5), new JLabel("6I"));
        hashtable.put(new Integer(6), new JLabel("7I"));
        hashtable.put(new Integer(7), new JLabel("8I"));
        hashtable.put(new Integer(8), new JLabel("9I"));
        hashtable.put(new Integer(9), new JLabel("PW"));
        hashtable.put(new Integer(10), new JLabel("SW"));
        clubsl.setLabelTable(hashtable);
        clubsl.setPaintLabels(true);
        clubsl.setPaintTicks(true);
        clubsl.setPreferredSize(new Dimension(300, 50));
        clubsl.setMinorTickSpacing(1);
        clubsl.setSnapToTicks(true);
        clubsl.addChangeListener(this);
        JPanel jpanel2 = new JPanel();
        jpanel2.add(clubsl);
        puttlabel = new JLabel();
        jpanel2.add(puttlabel);
        getContentPane().add(jpanel2, "South");
        strokes = new int[18];
        course = 1;
        hole = 1;
        total = 0;
        powerPanel.repaint();
        repaint();
    }

    public void stateChanged(ChangeEvent changeevent)
    {
        JSlider jslider = (JSlider)changeevent.getSource();
        if(!jslider.getValueIsAdjusting())
            club = jslider.getValue();
    }

    public void actionPerformed(ActionEvent actionevent)
    {
        if(actionevent.getActionCommand().equals("Swing"))
            if(!upSwing && !downSwing)
            {
                upSwing = true;
                (new SwingWorker() {

                    public Object construct()
                    {
                        while(!downSwing) 
                        {
                            powerPanel.incr();
                            powerPanel.repaint();
                            try
                            {
                                if(onGreen)
                                    Thread.sleep(10L);
                                else
                                    Thread.sleep(5L);
                            }
                            catch(InterruptedException interruptedexception) { }
                        }
                        return null;
                    }

            
                }).start();
            } else
            if(upSwing)
            {
                downSwing = true;
                upSwing = false;
                (new SwingWorker() {

                    public Object construct()
                    {
                        while(downSwing) 
                        {
                            powerPanel.ticktock();
                            powerPanel.repaint();
                            try
                            {
                                Thread.sleep(7L);
                            }
                            catch(InterruptedException interruptedexception) { }
                        }
                        return null;
                    }

            
                }).start();
            } else
            if(downSwing)
            {
                downSwing = false;
                inFlight = true;
                sb.setEnabled(false);
                strokes[hole - 1]++;
                total++;
                if(onGreen)
                {
                    if(theHole.terrain() == 0)
                        shotDist = 200D * powerPanel.getPPct();
                    else
                        shotDist = 150D * Math.pow(powerPanel.getPPct(), 1.5D);
                    maxSwerve = (1.5D * powerPanel.getSPct()) / shotDist;
                } else
                {
                    shotDist = CLUBDIST[theHole.terrain() - 1][club] * Math.pow(powerPanel.getPPct(), 1.5D);
                    maxSwerve = (3D * powerPanel.getSPct()) / shotDist;
                }
                (new SwingWorker() {

                    public Object construct()
                    {
                        for(double d = 0.0D; d < shotDist && !theHole.oob() && !inHole;)
                        {
                            theHole.moveBall(1.0D, maxSwerve * d, shotDist - d);
                            d += Math.sqrt(1.0D + Math.pow(maxSwerve * d, 2D));
                            theHole.repaint();
                            try
                            {
                                Thread.sleep(5L);
                            }
                            catch(InterruptedException interruptedexception) { }
                        }

                        if(theHole.terrain() == 4 || theHole.oob())
                        {
                            try
                            {
                                Thread.sleep(1000L);
                            }
                            catch(InterruptedException interruptedexception1) { }
                            theHole.reload();
                            strokes[hole - 1]++;
                            total++;
                        }
                        if(theHole.terrain() == 0 && !onGreen)
                        {
                            onGreen = true;
                            clubsl.setEnabled(false);
                            puttlabel.setText("Putting");
                            theHole.onGreen();
                            ulabel.setText("Feet");
                        }
                        inFlight = false;
                        powerPanel.reset();
                        slabel.setText((new Integer(strokes[hole - 1])).toString());
                        if(inHole)
                        {
                            repaint();
                            try
                            {
                                Thread.sleep(1000L);
                            }
                            catch(InterruptedException interruptedexception2) { }
                            if(hole <= 9)
                                nextHole();
                        }
                        repaint();
                        if(hole > 9)
                            theHole.scorecard();
                        return null;
                    }

                    }).start();
            }
    }

    private void nextHole()
    {
        hole++;
        if(hole <= 9)
        {
            onGreen = false;
            theHole.newHole("mhg" + course + "-" + hole + ".gif");
            clubsl.setValue(0);
            clubsl.setEnabled(true);
            puttlabel.setText("");
            plabel.setText((new Integer(PAR[course][hole - 1])).toString());
            slabel.setText("0");
            ulabel.setText("Yards");
            hlabel.setText((new Integer(hole)).toString());
            inHole = false;
        }
    }

    public void mouseEntered(MouseEvent mouseevent)
    {
    }

    public void mouseExited(MouseEvent mouseevent)
    {
    }

    public void mousePressed(MouseEvent mouseevent)
    {
    }

    public void mouseClicked(MouseEvent mouseevent)
    {
        int i = mouseevent.getX();
        int j = mouseevent.getY();
        if(theHole.intro())
        {
            if(i < 100 && j > 350)
            {
                theHole.newHole("mhg0-1.gif");
                repaint();
            }
        } else
        if(theHole.scoring())
        {
            if(i > 300 && j > 350 && course == 0)
            {
                if(total <= 40)
                    course = 1;
                hole = 0;
                strokes = new int[18];
                total = 0;
                nextHole();
            }
        } else
        if(!inFlight)
        {
            theHole.setBack(i, j);
            theHole.repaint();
            sb.setEnabled(true);
        }
    }

    public void mouseReleased(MouseEvent mouseevent)
    {
    }

    public void init()
    {
        SwingUtilities.invokeLater(new Runnable() {

            public void run()
            {
                makeGolf();
                repaint();
            }

        });
    }

    public static void main(String args[])
    {
        final JFrame jframe = new JFrame("Golf");
        final GifGolf gifgolf = new GifGolf();
        gifgolf.init();
        SwingUtilities.invokeLater(new Runnable() {

            public void run()
            {
                jframe.add(gifgolf);
                jframe.pack();
                jframe.setVisible(true);
            }

        });
    }

    private boolean upSwing;
    private boolean downSwing;
    private boolean inFlight;
    private boolean onGreen;
    private boolean inHole;
    PowerPanel powerPanel;
    CoursePanel theHole;
    JButton sb;
    private double shotDist;
    private double maxSwerve;
    private int club;
    private JSlider clubsl;
    private JLabel hlabel;
    private JLabel plabel;
    private JLabel ylabel;
    private JLabel slabel;
    private JLabel ulabel;
    private JLabel puttlabel;
    private int hole;
    private int course;
    private int total;
    private int strokes[];
    private final int NUMHOLES = 9;
    private final int CUTLINE = 40;
    private final double CLUBDIST[][] = {
        {
            280D, 250D, 230D, 215D, 200D, 185D, 170D, 155D, 140D, 125D, 
            100D
        }, {
            130D, 150D, 190D, 180D, 170D, 160D, 150D, 140D, 130D, 120D, 
            100D
        }, {
            80D, 80D, 170D, 160D, 150D, 145D, 140D, 135D, 130D, 120D, 
            100D
        }
    };
    private final int PAR[][] = {
        {
            4, 5, 3, 3, 5, 4, 3, 4, 4
        }, {
            4, 3, 4, 3, 5, 4, 5, 4, 3
        }
    };
    private final int HCP[][] = {
        {
            4, 2, 5, 8, 6, 7, 3, 9, 1
        }, {
            5, 6, 7, 3, 2, 9, 4, 8, 1
        }
    };
}
