package udp;

import java.awt.Color;
import java.awt.Font;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class Udp {

////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////ASCII:
static int [] ASCII = {  
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.',  10, '.', '.',  13, '.', '.',//0...15 
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',//16...31
' ', '!', '"', '#', '$', '%', '&', '.', '(', ')', '*', '+', ',', '-', '.', '/',//32...47
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',//48...63 
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',//64...79 
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '.', ']', '^', '_',//80...95 
'.', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',//96...111 
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', ' ',//112...127 
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',//128...143
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',//144...159 
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',//160...175 
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',//176...191
'А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ж', 'З', 'И', 'Й', 'К', 'Л', 'М', 'Н', 'О', 'П',//192...207 
'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ъ', 'Ы', 'Ь', 'Э', 'Ю', 'Я',//208...223 
'а', 'б', 'в', 'г', 'д', 'е', 'ж', 'з', 'и', 'й', 'к', 'л', 'м', 'н', 'о', 'п',//224...239
'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ъ', 'ы', 'ь', 'э', 'ю', 'я',//240...255
};
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////TX_Ethernet: 
static int xTX = 0;             // счёт xTX 
//static int [] TX_int = new int[1500];   //1500 Ethernet
static byte[] TX_byte = new byte[1500]; //1500 Ethernet
static String TX_IP = "";       // TX_IP Ethernet
//static int TX_len = 0;        // TX_len       
//static String UDP_TX = "";
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////RX_Ethernet: 
static int xRX = 0;             // счёт xRX 
static int [] RX_int = new int[1500];   //1500 Ethernet
static byte[] RX_byte = new byte[1500]; //1500 Ethernet
static int RX_port = 0;         // RX_port Ethernet
static int RX_len = 0;          // RX_len  
static String UDP_RX = ""; 
////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////// знаки HEX(int)> LCD(String): 
public static String LCD_HEX(int bi) {   
///////////////////
bi &= 0xFF;
int z = 0;
String HEX = "";  
///////////////////
z=0; while (bi>15) {z++; bi=bi-16;};     
if (z==0)  {HEX = "0";} if (z==1)  {HEX = "1";} if (z==2)  {HEX = "2";} if (z==3)  {HEX = "3";}
if (z==4)  {HEX = "4";} if (z==5)  {HEX = "5";} if (z==6)  {HEX = "6";} if (z==7)  {HEX = "7";}
if (z==8)  {HEX = "8";} if (z==9)  {HEX = "9";} if (z==10) {HEX = "A";} if (z==11) {HEX = "B";}
if (z==12) {HEX = "C";} if (z==13) {HEX = "D";} if (z==14) {HEX = "E";} if (z==15) {HEX = "F";}
///////////////////
z=0; while (bi>0)  {z++; bi=bi-1;};    
if (z==0)  {HEX += "0";} if (z==1)  {HEX += "1";} if (z==2)  {HEX += "2";} if (z==3)  {HEX += "3";}
if (z==4)  {HEX += "4";} if (z==5)  {HEX += "5";} if (z==6)  {HEX += "6";} if (z==7)  {HEX += "7";}
if (z==8)  {HEX += "8";} if (z==9)  {HEX += "9";} if (z==10) {HEX += "A";} if (z==11) {HEX += "B";}
if (z==12) {HEX += "C";} if (z==13) {HEX += "D";} if (z==14) {HEX += "E";} if (z==15) {HEX += "F";}
///////////////////
HEX += " ";
return HEX; //String
}
////////////////////////////////////////////////////////////////////////////////




////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////EEPROM:
static int xE = 0; // счёт EEPROM
////////////////////////////////////////////////////////////////////////////////
static long EEPROM_len = 0;      //EEPROM_len    
////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////// TX_EEPROM:    
public static void TX_EEPROM() {
//EEPROM_len = 0;               //сброс EEPROM_len           
//////////////////////////////////////////////////////// 
//////////////////////////////////////////////////////// TX: EEPROM:   
// ASCII UTF-8 !!! HEX
try  
{
//"rw" -файл открыт для чтения и записи (если файла нет, то файл будет создан "w").
//"r" -файл открыт для чтения (если файла нет, error).
RandomAccessFile E_raf = new RandomAccessFile("D:/Java.txt", "rw");
///////////////////////////////////////////проверка файла EEPROM:
EEPROM_len = E_raf.length();     //Возвращает длину файла EEPROM long
if (EEPROM_len > 1000000) {EEPROM_len = 0;}//MAX 
///////////////////////////////////////// запись файла EEPROM:
//курсор 
E_raf.seek(EEPROM_len); //  
for (xE=0; xE<RX_len; xE++) {        
  E_raf.writeByte(RX_int[xE]);// > write() // HEX      
};
///////////////////////////////////////// закрываем файл EEPROM:
//закрываем файл
E_raf.close();        
}catch(IOException e){

}       
/////////////////////////////////////////// TX EEPROM END
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////// RX_EEPROM:
public static void RX_EEPROM() {
EEPROM_len = 0;              //сброс EEPROM_len     
////////////////////////////////////////////////////////RX: EEPROM: 
// ASCII UTF-8 !!! HEX
try  
{
//"rw" -файл открыт для чтения и записи (если файла нет, то файл будет создан "w").
//"r" -файл открыт для чтения (если файла нет, error).
RandomAccessFile E_raf = new RandomAccessFile("D:/Java.txt", "r");//w
///////////////////////////////////////////проверка файла EEPROM:
//EEPROM_len = E_raf.length();     //Возвращает длину файла EEPROM long
/////////////////////////////////////////курсор EEPROM:
E_raf.seek(0);   
/////////////////////////////////////////читаем файл EEPROM:
for (xE=0; xE<1500; xE++) {        
  RX_int[xE] = E_raf.read();          //raf.read() > E_int //возвращает HEX или -1   
};
/////////////////////////////////////////// закрываем файл EEPROM
//закрываем файл
E_raf.close();        
}catch(IOException e){

}       
//////////////////////////////////////////////
}
////////////////////////////////////////////////////////////////////////////////




////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////настройка плеер_wavr:
///////////////////////////////////////////////
//8000,11025,16000,22050,44100
static int RX_sampleRate = 8000;    //8000 
//static int RX_sampleRate = 11025;   //11025
//static int RX_sampleRate = 16000;     //16000   
//static int RX_sampleRate = 22050;   //22050 
//static int RX_sampleRate = 44100;   //44100 
/////////////////////////////////////////////// 
static int RX_sampleSizeInBits = 8; //8 бит
//static int RX_sampleSizeInBits = 16;  //16 бит  
/////////////////////////////////////////////// Ethernet
static byte[] din_byte_wavr = new byte[1472]; 
////////////////////////////////////////////////////////////////////////////////




////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////// TX_Ethernet:
public static void TX_Ethernet(DatagramSocket socket) { 
 	 //////////////////////////////////////////////////////// TX: int > byte: 
	 for (xTX=0; xTX<RX_len; xTX++) {        // RX_len  
	    TX_byte[xTX] = (byte) RX_int[xTX];   // RX_int > TX_byte   
	 };
     //////////////////////////////////////////////////////// TX: Ethernet: 
     try
	 {
       DatagramPacket dp = new DatagramPacket(TX_byte, RX_len, InetAddress.getByName(TX_IP),RX_port);
       socket.send(dp);     // UDP: MIN=18; MAX=1472.
	 }catch(IOException e)
	 { 

	 }
	 ////////////////////////////////////////////////////////  
}
////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////поток 0: 
public static void main(String[] args) throws Exception
{
////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////Ethernet:
        final DatagramSocket socket = new DatagramSocket(80);
        //socket.setReceiveBufferSize(1);      // размер буфера RX Ethernet
////////////////////////////////////////////////////////////////////////////////
        //////////////////////////////////////////////////////////////////Color:	
	    final Color Fon = new Color(253, 245, 230); // фон 	    
	    Color FonText = new Color(25, 25, 112);     // Text
	    //YELLOW//LIGHT_GRAY//GREEN//YELLOW//CYAN
////////////////////////////////////////////////////////////////////////////////

        
////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////окно_LCD:
		final JFrame frame1 = new JFrame("окно_LCD"); 
		frame1.setBounds(10, 10, 1000, 550); // x,y,размер,размер
	    //остановить выполнение программы при закрытии окна
		frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		//не использует менеджеры по расположению элементов 
		frame1.setLayout(null);
        //фиксированный размер окна JFrame 
		frame1.setResizable(false);
	    //Не закрывать окно по нажатию на кнопку с крестиком 
		//frame1.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		/*
		//Слушатель frame1 - по нажатию на кнопку с крестиком 
		frame1.addWindowListener(new WindowListener() {  // Слушатель frame1
			public void windowActivated  (WindowEvent event) {}
            public void windowClosed     (WindowEvent event) {}
            public void windowDeactivated(WindowEvent event) {}
            public void windowDeiconified(WindowEvent event) {}
            public void windowIconified  (WindowEvent event) {}
            public void windowOpened     (WindowEvent event) {}
            // Метод обработки события "Закрытие окна"
            public void windowClosing (WindowEvent event) {
              EEPROM_TX();
              System.exit(0);//Завершение программы Java.//0 - нормальный режим Завершения
            }
        }); 
        */
////////////////////////////////////////////////////////////////////////////////
	    ///////////////////////////////////////////////////////// TextArea1 "RX"  
		final JTextArea ta1 = new JTextArea();       //"текст", 10, 20 
//		ta1.setBounds(5, 108, 982, 100);             // x,y,размер,размер
		ta1.setBackground(Fon);                      // RGB фон 
	    ta1.setForeground(FonText);                  // RGB Text  
	    //автоперенос на новую строку
		ta1.setLineWrap(true);                       // true/false
		//перенос длинных слов на новые строки целиком
		ta1.setWrapStyleWord(true);                  // true/false
		//шрифт 
		ta1.setFont(new Font("Dialog", Font.PLAIN, 14));
//	    frame1.add(ta1);                             // добавить 
	    /////////////////////////////////////////////// ScrollPane
		JScrollPane sp1  =  new  JScrollPane (ta1);
	    sp1.setBounds(5, 5, 982, 500);               // x,y,размер,размер
	    frame1.add(sp1);                             // добавить 
////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////вкл:
		frame1.setVisible(true);         // true/false // вкл окно_LCD         
////////////////////////////////////////////////////////////////////////////////
 
		

////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////// плеер_wavr:
	      int RX_channels = 1;           //1 моно, 2 стерео 
	      //true-знак(-127...+127/-32768...+32767)(8бит/16бит-PCM_SIGNED)
	      //boolean RX_signed = true;        
	      boolean RX_signed = false;   //false-без знака(0...255)(только 8бит-PCM_UNSIGNED)  
	      //boolean RX_bigEndian = false;//false little-endian//порядок байт
	      boolean RX_bigEndian = true;   //true big-endian;//порядок байт
	      AudioFormat RX_format = 
	      new AudioFormat(RX_sampleRate, RX_sampleSizeInBits, RX_channels, RX_signed, RX_bigEndian);
		  //////////////////////////////////////////////////// RX_wav:
	      //строка данных - для записи данных в буфер целевой строки данных.
		  SourceDataLine RX_line = null;
	      DataLine.Info RX_info = new DataLine.Info(SourceDataLine.class, RX_format);  
		  //////////////////////////////////////////////////// RX_wav:
	      try {
	    	RX_line = (SourceDataLine)AudioSystem.getLine(RX_info);
		  } catch (LineUnavailableException e1) {
			e1.printStackTrace();
		  }
		  //////////////////////////////////////////////////// RX_wav:
		  try {
			RX_line.open(RX_format);
		  } catch (LineUnavailableException e1) {
			e1.printStackTrace();
		  }
	      //////////////////////////////////////////////////// RX_wav: start:
	      RX_line.start();   
	      //RX_line.stop();
	      //RX_line.close();
////////////////////////////////////////////////////////////////////////////////
		
		
				
		
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////RX_Ethernet:
DatagramPacket reply = new DatagramPacket(RX_byte, RX_byte.length); 
while(true) 
{
  //////////////////////////////////////////////////////// RX: Ethernet:
  try
  {
    socket.receive(reply);            // UDP: MIN=18; MAX=1472.
    ////////////////////////////////////////////////////// RX: IP, port, len:  
    TX_IP = "" + reply.getAddress();  // IP String
    RX_port = reply.getPort();        // port int
    RX_len = reply.getLength();       // len int
  }catch(IOException e)
  {

  }
  //////////////////////////////////////////////////////// RX Ethernet END  
      //////////////////////////////////////////////////// RX: /TX_IP > TX_IP:
  	  //TX_IP = "/192.168.0.101" > TX_IP = "192.168.0.101" //String
	  byte[] b_TX_IP = TX_IP.getBytes();  // reply.getAddress();//String
	  TX_IP = "";                         // сброс TX_IP 
	  for (xRX=1; xRX<b_TX_IP.length; xRX++) { // смещение -1 
	  TX_IP += (char)b_TX_IP[xRX];      // byte > String TX_IP
	  };
      //////////////////////////////////////////////////// RX: byte > int: 
      for (xRX=0; xRX<RX_len; xRX++) {      // byte 0...127|-127...0 > int 0...255   
        RX_int[xRX] = RX_byte[xRX];   
        if (RX_int[xRX] < 0){RX_int[xRX] += 256;}
      };
	  //////////////////////////////////////////////////// RX: > HEX  
      UDP_RX = "TX_IP " + TX_IP + " | " + "len " + RX_len + " | " + " port " + RX_port + " | " + "\r\n";
      for (xRX=0; xRX<RX_len; xRX++) {       
        UDP_RX += LCD_HEX(RX_int[xRX]);      // HEX  
      };
      UDP_RX += "\r\n";
	  //////////////////////////////////////////////////// RX: > ASCII  
      //for (xRX=0; xRX<RX_len; xRX++) {       
      //  UDP_RX += (char)ASCII[ RX_int[xRX] ];// ASCII  
      //};
      //UDP_RX += "\r\n";
	  //////////////////////////////////////////////////// RX: > ta1 
      ta1.append(UDP_RX);                    // > TextArea 
	  //////////////////////////////////////////////////// RX: > Console  
      //System.out.println(UDP_RX);

      
      
	  //////////////////////////////////////////////////// RX: > TX_EEPROM 
      TX_EEPROM();
      //RX_EEPROM();
      
        ////////////////////////////////////////////////// RX: > RX_wavr  
		for (xRX=0; xRX<RX_len; xRX++) {      
	      din_byte_wavr[xRX] = (byte) RX_int[xRX];//int > din(динамик)
		};
		////////////////////////////////////////////////// RX: > RX_line:
		//Запись аудиоданных в выходной буфер линии передачи данных. 
		RX_line.write(din_byte_wavr, 0, RX_len);//RX_len 
	    //RX_line.stop();
      
		
		
      //////////////////////////////////////////////////// RX: > TX_Ethernet  
      //TX_Ethernet(socket);// > TX_Ethernet 
      //////////////////////////////////////////////////// RX: sleep
      //try {Thread.sleep(10);} catch (Exception e){} //ограничитель скорости CPU = 40%
      
}// while(true)    
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
}
}

