package de.heatup.ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.GridLayout;
import java.awt.Point;

import javax.swing.JFrame;
import javax.swing.JPanel;

import de.heatup.audio.AudioFiles;
import de.heatup.audio.AudioPlayer;
import de.heatup.cfg.Config;
import de.heatup.logging.Logger;
import de.heatup.mapengine.CollisionHandler;
import de.heatup.mapengine.MapEngine;
import de.heatup.mapengine.MapGrid;
import de.heatup.mapengine.SpawnAssistant;
import de.heatup.objects.Player;
import de.heatup.objects.StaticObject;
import de.heatup.timers.HardwareResetTimers;
import de.heatup.ui.actionPanel.ActionControl;
import de.heatup.ui.actionPanel.ActionWatcher;
import de.heatup.ui.menu.CreditsPanel;
import de.heatup.ui.menu.MenuPanel;


public class Main extends JFrame implements Runnable {
	
	private static final long serialVersionUID = 1L;
	
	private boolean running = false;
	private static boolean pause = false;
	private boolean fullscreen = false;
	
	private Thread thread;

	/**
	 * @deprecated
	 * BITTE DEN GETTER VERWENDEN!!!!11111ELF
	 */
	public static Player player01;
	
	private static JPanel outerPanel;
	private static JPanel statusPanel;
	private static JPanel gamePanel;
	private static JPanel leftPanel;
	private static JPanel rightPanel;
	private static JPanel actionPanel;
	private static JPanel creditsPanel;
	
	
	private static JPanel menuPanel;
	
	public void repack() {
		pack();
	}
	
	public Main(){
		setTitle("HeatUP!");
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setResizable(false);

		/*
		 * Vorbedingungen welche gesetzt sein müssen, damit Fullscreen möglich wird.
		 */
		if ( fullscreen) {
			setResizable(false);
			setUndecorated(true);
		}
		
		outerPanel = new JPanel();
		outerPanel.setLayout(new BorderLayout());
		outerPanel.setFocusable(true);

		statusPanel = new JPanel();
		statusPanel.setPreferredSize(new Dimension(800,80));
		statusPanel.setFocusable(false);

		gamePanel = new JPanel();
		gamePanel.setLayout(null);
		gamePanel.setPreferredSize(new Dimension(800,600));
		gamePanel.setFocusable(false);
		gamePanel.setBackground(Color.black);

		actionPanel = new JPanel();
		actionPanel.setLayout(new GridLayout(1,1));
		actionPanel.setPreferredSize(new Dimension(800,80));
		actionPanel.setFocusable(false);

		leftPanel = new JPanel();
		leftPanel.setLayout(null);
		leftPanel.setBackground(Color.black);

		rightPanel = new JPanel();
		rightPanel.setLayout(null);
		rightPanel.setBackground(Color.black);
		
		MenuPanel.setMenuPanel();
		menuPanel = MenuPanel.getMenuPanel();
				
		CreditsPanel.setCreditsPanel();
		creditsPanel = CreditsPanel.getCreditsPanel();
		
		outerPanel.add(statusPanel,BorderLayout.NORTH);
		outerPanel.add(leftPanel, BorderLayout.WEST);
		outerPanel.add(rightPanel, BorderLayout.EAST);
		outerPanel.add(gamePanel,BorderLayout.CENTER);
		outerPanel.add(actionPanel,BorderLayout.SOUTH);
		outerPanel.add(creditsPanel, BorderLayout.CENTER);
		outerPanel.add(menuPanel, BorderLayout.CENTER);		
		
		add(outerPanel);
		pack();		
		setVisible(true);				
		
		/*
		 * hier menue bauen
		 */
		PanelBuilder.setPanels(actionPanel, outerPanel, statusPanel, gamePanel);
		//PanelBuilder.startMenu();
		
		PanelBuilder.actionPanel.setBackground(Color.BLACK);
		PanelBuilder.statusPanel.setBackground(Color.BLACK);
				
		/*
		 * entfernen wenn getter verwendet wird.
		 */
		player01 = PanelBuilder.getPlayer();
		
		/*
		 * Wenn die Variable fullscreen gesetzt ist, wir er hier eingeschaltet.
		 */
		if ( fullscreen ) {
			GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
			GraphicsDevice gd = ge.getDefaultScreenDevice();
			GraphicsConfiguration gc = gd.getDefaultConfiguration();		
			gd.setFullScreenWindow(this);
			leftPanel.setPreferredSize(new Dimension(((gd.getDisplayMode().getWidth() - (int)gamePanel.getPreferredSize().getWidth())/2), 0));
			rightPanel.setPreferredSize(new Dimension(((gd.getDisplayMode().getWidth() - (int)gamePanel.getPreferredSize().getWidth())/2), 0));
		}
		outerPanel.setVisible(true);
		gamePanel.setVisible(true);
		actionPanel.setVisible(true);
		statusPanel.setVisible(true);
		
		/** 
		 * muss noch in den ClasLoader, loop für background sound geht 
		 */
		AudioFiles f = new AudioFiles();
		AudioPlayer p = new AudioPlayer();
		p.loop(f.getInvaders());
	}
	

	public static boolean getPause() {
		return pause;
	}
	
	public static void main(String[] args) {
		
		// Logging ausgabe auf Console aktivieren bzw. deaktivieren.
		Logger.enableLogging();
		
		EventQueue.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				final Main frame = new Main();
				frame.repaint();							
				Thread ht= new Thread(){

					@Override
					public void run() {
						frame.start();
					}
				};ht.start();ht.setName("Thread-zum-starten-von -GL");
			}
		});
		
		

		//GameInterface.getGamePanel().repaint();
		//GameInterface.getGamePanel().setComponentZOrder(dynO1, 1);
		//GameInterface.getGamePanel().add(dynO1);

		
	}
	
	public static synchronized void pause() {
		if (pause) {
			pause = false;
		} else {
			pause = true;
		}
	}
	
	public static Player getPlayer() {
		return PanelBuilder.getPlayer();
	}
	
	public synchronized void start() {
		if (running) {
			return;
		}
		running = true;
		thread = new Thread(this);
		thread.setName("GameLoopD");
		thread.start();
		
	}
	
	public synchronized void stop() {
		if (!running) {
			return;
		}
		
		running = false;
		try {
			thread.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.exit(1);
		
	}
	
	public void run() {
		
		long lastTime = System.nanoTime();
		final double targetTickAmount = 60.0;
		double ns = 1000000000 / targetTickAmount;
		double delta = 0;
		int updates = 0;
		int frames = 0;
		long timer = System.currentTimeMillis();
		
		while (running) {
			long now = System.nanoTime();
			delta += (now-lastTime) / ns;
			lastTime = now;
			if (delta >= 1) {
					tick();
				updates++;
				delta--;
			}
			render();
			frames++;
			
//			try {
//				thread.sleep(1); // entlastet die cpu massiv.				
//			} catch (InterruptedException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
			
			if (System.currentTimeMillis() - timer > 1000) {
				timer += 1000;
				this.setTitle("HeatUp" + updates +" Ticks, fps " + frames);
				//Logger.write(updates +" Ticks, fps " + frames);
				updates = 0;
				frames = 0;
			}
		}
		
		stop();
	}
	// alles was geupdatet werden muss hier rein
	private void tick() {
		
		if(MenuPanel.gameExists == 2) {
			PanelBuilder.kb.checkKeyActivity();
		}
		
		if (!pause) {
			if ( ! gamePanel.isVisible() ) {
				gamePanel.setVisible(true);
				actionPanel.setVisible(true);
				statusPanel.setVisible(true);
				
				menuPanel.setVisible(false);
				
			}
			PanelBuilder.tick();
		} else if ( pause ) {
			// Hier einfügen was passiert wenn ESC gedrückt wird
			
			outerPanel.setBackground(Color.BLACK);
			
			gamePanel.setVisible(false);
			actionPanel.setVisible(false);
			statusPanel.setVisible(false);
			
			menuPanel.setVisible(true);
		}
	}
	// alles was animiert wird hier rein (paints)
	private void render() {
//		player01.repaint();
//		outerPanel.repaint();
		gamePanel.repaint();
//		actionPanel.repaint();
//		statusPanel.repaint();
//		this.repaint();
	}

}
