package me.netux.ducksarethebest;

import java.awt.Color;
import java.awt.Desktop;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class DucksAreTheBest extends JFrame {

	/* Some ducky variables */
	private static String[] titles, quacks;
	private static Clip quack;
	private static int pickedQuack;
	private static Color bgColor;
	private static boolean showKeys;
	
	public static void main(String[] args) {
		/* Defining ducky variables */
		quacks = new String[] { "ducktales.wav", "quack.wav", "chic.wav", "duck-run.wav", "ducks-conver.wav" };
		showKeys = true;
		pickedQuack = new Random().nextInt(quacks.length);
		bgColor = Color.WHITE;
		titles = new String[] { 
			"WHAT DO YOU CALL A THEIVING DUCK? A ROBBER DUCK",
			"DUCK JOKES ARE FOWL",
			"THEY SHOULD HAVE DUCKTORS INSTEAD OF VETS",
			"DUCKS QUACK ME UP"
		};
		
		/* Opening da window */
		new DucksAreTheBest();
	}
	
	public DucksAreTheBest() {
		/* Some misc stuff */
		setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("ducky-resources/duckling.png")));
		setTitle(titles[new Random().nextInt(titles.length)]);
		setSize(Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height);
		setExtendedState(MAXIMIZED_BOTH);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setCursor(Toolkit.getDefaultToolkit().createCustomCursor(Toolkit.getDefaultToolkit().getImage(getClass().getResource("ducky-resources/null-cursor.png")), new Point(0, 0), "Null"));
		
		/* Music stuff */
		if(!resetMuseek()) {
			System.exit(0);
			return;
		}
		
		/* Starting da thing to draw the duck pics */
		final DuckyBoard b = new DuckyBoard();
		b.addMouseMotionListener(new MouseMotionListener() {
			
			@Override
			public void mouseMoved(MouseEvent e) {
				/* Checking for da Mouse movement and adding da ducky ducks */
				b.ducks.add(e.getPoint());
				repaint();
			}
			
			@Override
			public void mouseDragged(MouseEvent e) {
				/* Just in case c: */
				mouseMoved(e);
			}
			
		});
		add(b);
		
		/* Key Stuff */
		addKeyListener(new KeyListener() {
			
			@Override
			public void keyPressed(KeyEvent e) {
				/* Reset it all m8 */
				if(e.getExtendedKeyCode() == 116) {
					b.ducks.clear();
					repaint();
					resetMuseek();
				}
				
				/* Send to the webpage */
				if(e.getExtendedKeyCode() == 87) {
					try { Desktop.getDesktop().browse(new URI("http://ducksarethebest.com/")); }
					catch (IOException | URISyntaxException x) { }
					System.exit(0);
				}
			}
			
			@Override
			public void keyTyped(KeyEvent e) { }
			
			@Override
			public void keyReleased(KeyEvent e) { }
			
		});
		
		/* Background stuff */
		new Thread(new Runnable() {
			@Override
			public void run() {
				while(true) {
					bgColor = randomColor();
					repaint();
					try { Thread.sleep(400); }
					catch (InterruptedException x) { }
				}
			}
		}).start();
		
		setVisible(true); /* Opening it all so you can quack c: */
	}
	
	/* Museek stuff */
	private boolean resetMuseek() {
		try {
			if(quack == null) quack = AudioSystem.getClip();
			quack.close();
			quack.flush();
			quack.open(AudioSystem.getAudioInputStream(getClass().getResource("ducky-resources/" + quacks[pickedQuack])));
			quack.loop(Clip.LOOP_CONTINUOUSLY);
			quack.start();
			return true;
		} catch (LineUnavailableException | IOException | UnsupportedAudioFileException x) { return false; }
	}
	
	/* Getting a random color for the background */
	public static Color randomColor() {
//		return new Color(new Random().nextInt(255), new Random().nextInt(255), new Random().nextInt(255)); Uses too much resources D;
		return new Color((int) Math.floor(Math.random() * 255), (int) Math.floor(Math.random() * 255), (int) Math.floor(Math.random() * 255));
	}
	
	class DuckyBoard extends JPanel {
		
		/* Ducks go here */
		public List<Point> ducks = new ArrayList<>();
		
		public void paint(Graphics g) {
			Graphics2D g2 = (Graphics2D) g;
			
			/* Background stuff 2.0 */
			g2.setColor(bgColor);
			g2.fillRect(0, 0, getWidth(), getHeight());
			
			/* Gotta add 'em all */
			for(Point p : ducks) g2.drawImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("ducky-resources/duck.png")), p.x, p.y, null);
			
			/* Info Text */
			if(!showKeys) return;
			g2.setColor(Color.BLACK);
			g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
			g2.setFont(new Font("Verdana", Font.PLAIN, 15));
			g2.drawString("W: Go to original webpage", getX(), getHeight() - 20);
			g2.drawString("F5: Restart", getX(), getHeight() - 5);
		}
		
	}

}
