/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License") +  you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.openmeetings.test.rdc;

import java.awt.*;
import java.awt.event.*;

class WindowClosingAdapter extends WindowAdapter {
	public void windowClosing(WindowEvent event) {
		event.getWindow().setVisible(false);
		event.getWindow().dispose();
		System.exit(0);
	}
}

public class KeyCodesTest extends Frame implements KeyListener {
	private static final long serialVersionUID = -1706968644784929402L;
	String msg1 = "";
	String msg2 = "";

	public static void main(String[] args) {
		new KeyCodesTest();
	}

	public KeyCodesTest() {
		super("TestKeyCodes");
		addKeyListener(this);
		addWindowListener(new WindowClosingAdapter());
		setBackground(Color.lightGray);
		setSize(300, 200);
		setLocation(200, 100);
		setVisible(true);
	}

	public void paint(Graphics g) {
		if (msg1.length() > 0) {
			draw3DRect(g, 20, 50, 250, 30);
			g.setColor(Color.black);
			g.drawString(msg1, 30, 70);
		}
		if (msg2.length() > 0) {
			draw3DRect(g, 20, 100, 250, 30);
			g.setColor(Color.black);
			g.drawString(msg2, 30, 120);
		}
	}

	void draw3DRect(Graphics g, int x, int y, int width, int height) {
		g.setColor(Color.darkGray);
		g.drawLine(x, y, x, y + height);
		g.drawLine(x, y, x + width, y);
		g.setColor(Color.white);
		g.drawLine(x + width, y + height, x, y + height);
		g.drawLine(x + width, y + height, x + width, y);
	}

	public void keyPressed(KeyEvent event) {
		msg1 = "";
		System.out.println("keyPressed CODE1 "+event.getKeyCode());
		
		Integer myCode = event.getKeyCode();
		
		System.out.println("keyPressed CODE2 "+myCode);
		
		System.out.println("keyPressed CHAR3 "+event.getKeyChar());
		
		System.out.println("keyPressed CHAR4 "+KeyEvent.getKeyText(event.getKeyCode()));
		
		System.out.println("keyPressed CHAR5 "+KeyEvent.getKeyText(myCode));
		
		System.out.println("keyPressed isActionKey "+event.isActionKey());
		System.out.println("keyPressed isAltDown "+event.isAltDown());
		System.out.println("keyPressed isAltGraphDown "+event.isAltGraphDown());
		System.out.println("keyPressed isConsumed "+event.isConsumed());
		System.out.println("keyPressed isControlDown "+event.isControlDown());
		System.out.println("keyPressed isMetaDown "+event.isMetaDown());
		System.out.println("keyPressed isShiftDown "+event.isShiftDown());

		System.out.println("keyPressed paramString "+event.paramString());
		
		if (event.getKeyChar() == KeyEvent.CHAR_UNDEFINED) {
			int key = event.getKeyCode();
			// Funktionstaste abfragen
			if (key == KeyEvent.VK_F1) {
				msg1 = "F1";
			} else if (key == KeyEvent.VK_F2) {
				msg1 = "F2";
			} else if (key == KeyEvent.VK_F3) {
				msg1 = "F3";
			}
			// Modifier abfragen
			if (msg1.length() > 0) {
				if (event.isAltDown()) {
					msg1 = "ALT + " + msg1;
				}
				if (event.isControlDown()) {
					msg1 = "STRG + " + msg1;
				}
				if (event.isShiftDown()) {
					msg1 = "UMSCHALT + " + msg1;
				}
			}
		}
		repaint();
	}

	public void keyReleased(KeyEvent event) {
		msg1 = "";
		repaint();
	}

	public void keyTyped(KeyEvent event) {
		char key = event.getKeyChar();
		
//		System.out.println("keyTyped CODE1 "+event.getKeyCode());
//		
//		Integer myCode = event.getKeyCode();
//		
//		System.out.println("keyTyped CODE2 "+myCode);
//		
//		System.out.println("keyTyped CHAR3 "+event.getKeyChar());
//		
//		System.out.println("keyTyped CHAR4 "+event.getKeyText(event.getKeyCode()));
//		
//		System.out.println("keyTyped CHAR5 "+event.getKeyText(myCode));
		
		if (key == KeyEvent.VK_BACK_SPACE) {
			if (msg2.length() > 0) {
				msg2 = msg2.substring(0, msg2.length() - 1);
			}
		} else if (key >= KeyEvent.VK_SPACE) {
			if (msg2.length() < 40) {
				msg2 += event.getKeyChar();
			}
		}
		repaint();
	}
}
