/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * FirePanel.java
 *
 * Created on 08.03.2010, 12:21:17
 */

package csa.gui.panels;

import csa.gui.*;
import csa.sound.*;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
import java.io.*;
import java.awt.color.*;
import java.awt.*;
import java.awt.event.*;

/**
 *
 * code adapted from: http://www.eigelb.at/HP/Links/SpecialEffects/Glitzer/Glitzer3.html
 */
public class GlitterPanel1 extends javax.swing.JPanel implements Runnable{

    // Maximum Number of particles - default: 1000
    private static final int PARTIKEL_NO = 1000;
    //strength of random starting-Motion of particles - default: 30
    private static final int SPREADING = 30;
    // dynamic mouse-behaviour, "y" for on or "n" for off - default: true
    private static final boolean MOUSE_DYNAMIC = true;
    // How fast particles dissappear - default: 25
    private static final int AGING = 25;
    // How many particles appear per round - default: 20
    private static final int FREQUENCY = 20;
    // The power of Gravity (0=no gravity) - default: 10
    private static final int GRAVITY = 10;
    // Name of background-image (null if you do not use one)
    private static final String BACK_IMAGE = null;
    // Brightness of particles - default: 90
    private static final int BRIGHTNESS=90;


    int backShade =100;
    int animDelay = 30;

    boolean firstUpdate = true;
    Thread animator = null;
    boolean doRun = false;
    boolean deinit=false;
    int width = 200;
    int height = 200;
    Color backColor = new Color(0,0,0,backShade);


    public GlitterPanel1() {
        setOpaque(false);
        setDoubleBuffered(false);
        super.setVisible(false);
        initComponents();
    }

    public void setDelay(int d)
    {
        animDelay=d;
    }


    public void deinit()
    {
        setVisible(false);
        removeAll();
        x = null;
        y = null;
        g = null;
        d = null;
        p = null;
        partikelField = null;
        partikelVisible = null;
        partikelA = null;
        colorMap = null;
        workImage = null;
        imageGraphicContext = null;
    }

    @Override public void setVisible(boolean b)
    {
        if (deinit) return;
        if (b==isVisible()) return;
        super.setVisible(b);

        if ( b )
        {
            if (animator == null)
            {
                animator = new Thread(this);
                doRun = true;

                height=getHeight();
                width=getWidth();
            	init();

                animator.start();
            }
        }
        else
        {
            if (animator != null)
            {
                synchronized (this)
                {
                    doRun = false;
                    animator.interrupt();
                    animator = null;
                }
            }
        }
    }

    // Run the animation thread.
    // First wait for the background image to fully load
    // and paint.  Then wait for all of the animation
    // frames to finish loading. Finally, loop and
    // increment the animation frame index.
    public void run()
    {
        if (deinit) return;
        while (doRun)
        {
            try
            {
                Thread.sleep(animDelay);
                update();
            }
            catch (InterruptedException e)
            {
                break;
            }
            synchronized (this)
            {
            }
            repaint();
        }
    }

    /** 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.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        setOpaque(false);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents

    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables


    public void init()
    {
        if (deinit) return;

        u = true;
        imageLoadState = 0;
        w = false;
        mouseButtonPressed = false;
        linkCursorSet = false;
        lastXMousePos = 0;
        lastYMousePos = 0;
        xMotionEvent = 0;
        yMotionEvent = 0;
        oldLastXMousePos = 0;
        oldLastYMousePos = 0;
        q = 0.0D;
        b = 0.050000000000000003D;
        colorCount = 256;
        i = 0;
        partikelNo = 2000;
        hasMouseDynamic = true;
        spreading = 35D;
        aging = 0.96999999999999997D;
        frequency = 20;
        gravity = 1.0D;



        workWidth = width;
        workHeigth = height;
        partikelNo = PARTIKEL_NO;
        spreading = SPREADING;
        hasMouseDynamic = MOUSE_DYNAMIC;
        aging = 1.0D - 0.001D * (double)AGING;
        frequency = FREQUENCY;
        gravity = 0.10000000000000001D * (double)GRAVITY;
        bgImageName = BACK_IMAGE;
        brightness = 0.029999999999999999D * (double)BRIGHTNESS;
        x = new double[partikelNo];
        y = new double[partikelNo];
        g = new double[partikelNo];
        d = new double[partikelNo];
        p = new double[partikelNo];
        partikelField = new double[partikelNo];
        partikelVisible = new boolean[partikelNo];
        partikelA = new int[partikelNo];
        for(int i1 = 0; i1 < partikelNo; i1++)
            partikelVisible[i1] = false;

        colorMap = new Color[colorCount];
        for(int j1 = 0; j1 < colorCount; j1++)
        {
            int i2 = j1;
            if(i2 > 255)
                i2 = 255;
            int l1 = (int)(2D * (double)j1);
            if(l1 > 255)
                l1 = 255;
            int k1 = (int)(4D * (double)j1);
            if(k1 > 255)
                k1 = 255;
            colorMap[j1] = new Color(k1, l1, i2);
        }

        addMouseListener(new GlitterMouseListener());
        addMouseMotionListener(new GlitterMouseMotionListener());

        firstUpdate = true;
    }

    private void update()
    {
        if (firstUpdate)
        {
            imageLoadState = 1;
            /*
            if(bgImageName != null)
            {
                mediaTracker = new MediaTracker(this);
                image = getImage(getDocumentBase(), bgImageName);
                mediaTracker.addImage(image, 0);
                mediaTracker.checkID(0, true);
                c.setColor(Color.black);
                c.fillRect(0, 0, workWidth, workHeigth);
                c.setColor(Color.white);
                c.drawString("loading image...", 10, 25);
                repaint();
                while(!mediaTracker.checkAll())
                    try
                    {
                        a _tmp = this;
                        Thread.sleep(50L);
                    }
                    catch(InterruptedException interruptedexception) { }
            }
             */
            workImage = createImage(workWidth, workHeigth);
            if (workImage != null)
            {
                imageGraphicContext = workImage.getGraphics();
                imageLoadState = 2;
                firstUpdate = false;
            }
            else
            {
                return;
            }
        }
        q += b;
        int j1 = 0;
        if(!w || mouseButtonPressed)
        {
            w = true;
            for(int i1 = 0; i1 < partikelNo; i1++)
                if(j1 < frequency && !partikelVisible[i1] && mouseButtonPressed)
                {
                    double d1 = (1.0D * (double)j1) / (double)frequency;
                    x[i1] = oldLastXMousePos + (int)(d1 * (double)(lastXMousePos - oldLastXMousePos)) + (int)(0.10000000000000001D * spreading * (Math.random() - 0.5D));
                    y[i1] = oldLastYMousePos + (int)(d1 * (double)(lastYMousePos - oldLastYMousePos)) + (int)(0.10000000000000001D * spreading * (Math.random() - 0.5D));
                    g[i1] = spreading * (Math.random() - 0.5D);
                    d[i1] = spreading * (Math.random() - 0.5D);
                    if(hasMouseDynamic)
                    {
                        g[i1] += 3 * (lastXMousePos - oldLastXMousePos);
                        d[i1] += 3 * (lastYMousePos - oldLastYMousePos);
                    }
                    partikelField[i1] = brightness * (0.25D + Math.random());
                    p[i1] = 15D * Math.random();
                    partikelA[i1] = (int)(1.5D * Math.random());
                    partikelVisible[i1] = true;
                    j1++;
                    w = false;
                } else
                if(partikelVisible[i1])
                {
                    w = false;
                    d[i1] += gravity;
                    g[i1] *= 0.96999999999999997D;
                    d[i1] *= 0.96999999999999997D;
                    x[i1] += b * g[i1];
                    y[i1] += b * d[i1];
                    partikelField[i1] *= aging;
                    if(y[i1] > (double)workHeigth || x[i1] < 0.0D || x[i1] > (double)workWidth || partikelField[i1] < 0.40000000000000002D)
                        partikelVisible[i1] = false;
                }

        }
        oldLastXMousePos = lastXMousePos;
        oldLastYMousePos = lastYMousePos;
        lastXMousePos = xMotionEvent;
        lastYMousePos = yMotionEvent;
        repaint();
    }

    @Override public void paintComponent(Graphics g1)
    {
        if (deinit) return;
        if(imageLoadState == 2)
        {
         //   g1.setColor(backColor);
         //   g1.fillRect(0, 0, width, height);
        

            if(image == null)
            {
//                imageGraphicContext.setColor(new Color(0,0,0,1));
                // imageGraphicContext.setColor(backColor);
                // imageGraphicContext.clearRect(0, 0, workWidth, workHeigth);
                imageGraphicContext.setColor(backColor);
                imageGraphicContext.fillRect(0, 0, workWidth, workHeigth);
            }
            else
            {
                imageGraphicContext.drawImage(image, 0, 0, this);
            }

//            imageGraphicContext.setColor(new Color(150, 150, 150));
//            imageGraphicContext.drawString("more applets on this link:", 10, workHeigth - 25);
//            if(n > workHeigth - 24 && o < 120)
//                imageGraphicContext.setColor(Color.white);
//            imageGraphicContext.drawString("http://www.eigelb.at", 10, workHeigth - 10);
            if(!w)
            {
                for(int i1 = 0; i1 < partikelNo; i1++)
                    if(partikelVisible[i1])
                    {
                        double d1 = partikelField[i1] * (1.5D + Math.sin(q * p[i1]));
                        int j1 = (int)x[i1];
                        int k1 = (int)y[i1];
                        if(d1 > 1.5D)
                        {
                            int l1 = (int)(d1 - 0.5D);
                            i = (int)(40D * d1);
                            if(i >= colorCount)
                                i = colorCount - 1;
                            imageGraphicContext.setColor(colorMap[i]);
                            if(partikelA[i1] == 0)
                            {
                                imageGraphicContext.fillRect(j1 - l1, k1, 2 * l1, 1);
                                imageGraphicContext.fillRect(j1, k1 - l1, 1, 2 * l1);
                            } else
                            {
                                imageGraphicContext.drawLine(j1 - l1, k1 - l1, j1 + l1, k1 + l1);
                                imageGraphicContext.drawLine(j1 + l1, k1 - l1, j1 - l1, k1 + l1);
                            }
                        }
                        i = (int)(100D * d1);
                        if(i >= colorCount)
                            i = colorCount - 1;
                        imageGraphicContext.setColor(colorMap[i]);
                        imageGraphicContext.fillRect(j1, k1, 1, 1);
                    }
            }
            g1.drawImage(workImage, 0, 0, this);
        }
//        else
//        if(imageLoadState == 1)
//            g1.drawImage(workImage, 0, 0, this);
    }
    Thread v;
    Image workImage;
    Graphics imageGraphicContext;
    Image image;
    MediaTracker mediaTracker;
    int workWidth;
    int workHeigth;
    int z;
    int _flddo;
    boolean u;
    int imageLoadState;
    boolean w;
    boolean mouseButtonPressed;
    boolean linkCursorSet;
    int lastXMousePos;
    int lastYMousePos;
    int xMotionEvent;
    int yMotionEvent;
    int oldLastXMousePos;
    int oldLastYMousePos;
    double q;
    double b;
    double x[];
    double y[];
    double g[];
    double d[];
    double partikelField[];
    double p[];
    boolean partikelVisible[];
    int partikelA[];
    Color colorMap[];
    int colorCount;
    int i;
    int partikelNo;
    boolean hasMouseDynamic;
    double spreading;
    double aging;
    int frequency;
    double gravity;
    String bgImageName;
    double brightness;

    class GlitterMouseMotionListener extends MouseMotionAdapter
    {

        public void mouseMoved(MouseEvent mouseevent)
        {
            mouseDragged(mouseevent);
        }

        public void mouseDragged(MouseEvent mouseevent)
        {
            xMotionEvent = mouseevent.getX();
            yMotionEvent = mouseevent.getY();
        }

        GlitterMouseMotionListener()
        {
        }
    }

    class GlitterMouseListener extends MouseAdapter
    {

        public void mousePressed(MouseEvent mouseevent)
        {
            mouseButtonPressed = true;
        }

        public void mouseReleased(MouseEvent mouseevent)
        {
            mouseButtonPressed = false;
        }

        GlitterMouseListener()
        {
        }
    }


}