/* 【Javaネット温湿度計】(TR-72W/Multicast)
 * (1) java -cp DIR MulticastClientTR72W DIR
 * (2) java -jar DIR/MulticastClientTR72W.jar DIR
 * copyright Koji Wada 2005
 */

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.event.*;
import java.util.*;
import java.lang.*;
import java.util.Timer;
import java.util.TimerTask;
import java.net.URL;
import javax.swing.JRadioButton;
import javax.swing.ButtonGroup;
import java.io.*;
import java.awt.image.*;
import java.util.jar.*;

public class MulticastClientTR72W implements Runnable {
  public static int WinOffsetX = 4;
  public static int WinOffsetY = -28;

  public static double ondo = 0;
  public static double current;
  public static JSlider sl;
  public static int flag = 0;	    // タイマ起動後にデータ表示
  public static int ledflag = 0;	// 小数点点滅用フラグ
  public static int timer;
  public static DigCanvas mc;
  public static JRadioButton radio1, radio2;
  
  public static PushButton a;
  public static PushButton b;

  public static String s = "T";
  public static int slmax = 50;
  public static String ip;
  public static String fip = "";
  public static int joinflag = 0;
  static String dat[] = new String[10];
  static String dir;

  // メイン・フレームのサイズ
  int WxSize = 100;
  int WySize = 328;

  public MulticastClientTR72W() {
    // フレームを生成(タイトル表示)
    JFrame frame = new JFrame("TR72W.");
    // 背景画像
    frame.setContentPane(new ImageComponent());
    // 終了処理
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    // 温度表示用スライダ
    sl = new JSlider(JSlider.VERTICAL, 0, slmax, 0);
    sl.setPaintTrack(true);
    sl.setMajorTickSpacing(10);
    sl.setMinorTickSpacing(1);
    sl.setPaintTicks(true);
    sl.setPaintLabels(true);
    sl.setSnapToTicks(true);
    sl.setValue((int)current);
    sl.putClientProperty("JSlider.isFilled", Boolean.TRUE);
    sl.setBackground(Color.black);	// Windows の場合はコメントアウト
    sl.setForeground(Color.orange);	// Windows の場合はほかの色
    sl.setFont(new Font("TimesRoman", Font.BOLD, 300));
    // レイアウト・マネジャ(縦一列を想定)
    GridBagLayout gridbag = new GridBagLayout();
    GridBagConstraints c = new GridBagConstraints();
    frame.getContentPane().setLayout(gridbag);
    
    // (1)
    c.insets = new Insets(0, 0, 0, 0);
    c.gridx = 0;
    c.gridy = 0;
    c.gridwidth = 1;
    c.gridheight = 1;
    c.weightx = 0.0;
    c.weighty = 0.0;
    // ラベル表示
    JLabel name = new JLabel("TR72W.");
    name.setForeground(Color.black);
    gridbag.setConstraints(name, c);
    frame.getContentPane().add(name);
    
    // (2)
    c.insets = new Insets(0, 0, 0, 0);
    c.gridx = 0;
    c.gridy = 1;
    c.gridwidth = 1;
    c.gridheight = 1;
    c.weightx = 0.0;
    c.weighty = 0.0;
    // 温度用スライダ台紙
    bgJPanel pp = new bgJPanel(78, 180);
    pp.setPreferredSize(new Dimension(78, 185));
    pp.add(sl);
    pp.setBackground(Color.black);
    gridbag.setConstraints(pp, c);
    frame.getContentPane().add(pp);

    // (3)
    c.insets = new Insets(0, 0, 0, 0);
    c.gridx = 0;
    c.gridy = 2;
    c.gridwidth = 1;
    c.gridheight = 1;
    c.weightx = 0.0;
    c.weighty = 0.0;	// 密着
    // ディジタル表示部台紙
    JPanel p = new JPanel();
    p.add(mc);
    p.setBackground(Color.black);
    gridbag.setConstraints(p, c);
    frame.getContentPane().add(p);
    
    // (4) 最下部
    c.insets = new Insets(0, 0, 0, 0);
    c.gridx = 0;
    c.gridy = 3;
    c.gridwidth = 1;
    c.gridheight = 1;
    c.weightx = 0.0;
    c.weighty = 0.0;
    // 温湿度選択ボタン作成
    new PushButton();
    new PushButton2();
    
    // ラジオ・ボタン・グループ
    ButtonGroup bGroup = new ButtonGroup();
    // ボタンのグループ登録
    bGroup.add(radio1);
    bGroup.add(radio2);
    // ラジオ・ボタンの台紙
    MyJPanelRadio myJPanelRadio = new MyJPanelRadio(10, 10);
    // ラジオ・ボタン登録
    // OK
    
    myJPanelRadio.add(radio1);
    myJPanelRadio.add(radio2);
    // ラジオ・ボタンリスナー登録
    radio1.addActionListener(myJPanelRadio);
    radio2.addActionListener(myJPanelRadio);
    // ラジオ・ボタンの台紙の登録
    gridbag.setConstraints(myJPanelRadio, c);
    frame.getContentPane().add(myJPanelRadio);
    
    // サイズを指定して表示開始
    frame.setSize(WxSize, WySize);
    frame.show();
    // サイズ変更禁止
    frame.setResizable(false);
  }

  // 画像の取り出し(画像)
  static class ImageComponent2 extends JComponent {
    Image getImageData(String pixName, String dir) {
      Image img;
      File theFile = new File(dir + "MulticastClientTR72W.jar");
      String path = "images/";
      if (theFile.exists()) {
        // jarファイルからイメージ・データを取り出す
        ClassLoader cl = this.getClass().getClassLoader();
        Toolkit toolkit = new Frame().getToolkit();
        img = toolkit.getImage(cl.getResource(path + pixName));
        return img;
      } else {
        theFile = new File(dir + path + pixName);
        if (theFile.exists()) {
          // イメージ・ファイルからイメージを読み出す
          Toolkit toolkit = new Frame().getToolkit();
          img = toolkit.getImage(dir + path + pixName);
          return img;
        } else {
          System.out.println("No Image file.");
        }
      }
      return null;
	}
  }
  
  // 画像の取り出し(ボタン)
  static class ImageComponent3 extends JComponent {
	Image getImageData3(String pixName, String dir) {
      Image img;
      File theFile = new File(dir + "MulticastClientTR72W.jar");
      String path = "images/";
      if     (theFile.exists()) {
        // jarファイルからイメージ・データを取り出す
        try {
          JarFile jFile = new JarFile(theFile);
          InputStream in = jFile.getInputStream(jFile.getEntry(path + pixName));
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          byte[] b = new byte[1024];
          int i;
          while ((i = in.read(b)) != -1) {
            baos.write(b, 0, i);
          }
          byte[] pix = baos.toByteArray();
          img = Toolkit.getDefaultToolkit().createImage(pix);
          return img;
        } catch (IOException e) {
          ;
        }
      } else {
        theFile = new File(dir + path + pixName);
        if (theFile.exists()) {
          // イメージ・ファイルからイメージを読み出す
          Toolkit toolkit = new Frame().getToolkit();
          img = toolkit.getImage(dir + path + pixName);
          return img;
        } else {
          System.out.println("No Image file.");
        }
      }
      return null;
	}
  }
  
  // ラジオ・ボタン台紙を準備
  public static class MyJPanelRadio extends JPanel implements ActionListener {
	public MyJPanelRadio(int x, int y) {
      super();
      ///  this.setSize(x, y);
	}
	// 動作設定
    public void actionPerformed(ActionEvent e) {
      JRadioButton curRButton = (JRadioButton) e.getSource();
      if (curRButton == radio1) {
        s = "T";
      }
      if (curRButton == radio2) {
        s = "H";
      }
    }

    // 背景画像
    public void
    paintComponent(Graphics g) {
      int i, j;
      Toolkit toolkit = getToolkit();
      ImageComponent2 imgConpo = new ImageComponent2();
      Image imgbis = imgConpo.getImageData("radio-back.jpg", dir);
      g.drawImage(imgbis, 0, 0, this);
      g.drawString("T", 21, 32);
      g.drawString("H", 51, 32);
    }
  }

  // メイン背景画像用意
  class ImageComponent extends JComponent {
    public void paintComponent(Graphics g) {
      Image img;
      ImageComponent2 imgConpo = new ImageComponent2();
      img = imgConpo.getImageData("tr72w-base-3.jpg", dir);
      g.drawImage(img, 0, 0, WxSize + WinOffsetX, WySize + WinOffsetY, this);
    }
  }

  // 背景画像張り付け可能なパネル
  public static class bgJPanel extends JPanel {
    // サイズ指定可能
    public bgJPanel(int x, int y) {
      super();
      // サイズ・セット
      /// this.setSize(x, y);
    }
    
    public void paint(Graphics g) {
      Image image, img;
      super.paint(g);
      // アクリル・パネル風処理(グラデーション)
      Graphics2D g2 = (Graphics2D) g;
      GradientPaint gp = new GradientPaint(0, 60, Color.black, 1, 6, Color.white, true);
      g2.setPaint(gp);
      // アクリル・パネル風処理(透明)
      Composite comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3F);
      g2.setComposite(comp);
      g2.fillRect(0, 0, 300, 400);
    }
  }
  
  // メイン
  public static void main(String args[]) {
    // ディレクトリ指定オプション
    if(args.length > 0) {
      dir = args[0] + "/";
    } else {
      dir = "";
    }
    mc = new DigCanvas(68, 50);
    a = new PushButton();
    b = new PushButton();
    // 自身を作成
    MulticastClientTR72W thermo = new MulticastClientTR72W();
    // タイマを用意
    Timer timer = new Timer(true);
    blinkTask task = new blinkTask();
    timer.schedule(task, 0, 1000);
    // 描画更新開始
    thermo.start();
  }
  
  // 点滅表示用タイマ
  public static class blinkTask extends TimerTask {
    blinkTask() {
      ;
    }
    // フラグの更新のみ
    public void run() { if (ledflag++ == 2) {
      ledflag = 0;
    }
    mc.repaint();
    }
  }
  
  // スレッド
  public void
  start() {
    Thread thread = new Thread(this);
    thread.start();
  }
  
  // スレッド本体
  public void
  run() {
    // MulticastDataGet
    MulticastDataGet a = new MulticastDataGet();
    Thread t = new Thread(a);
    t.start();
    while (true) {
      // 温度データを取得
      StringTokenizer st = new StringTokenizer(MulticastDataGet.oneData(), " ");
      int i, j;
      j = st.countTokens();
      for (i = 0; i < j; i++) {
        dat[i] = st.nextToken();
      }
      // 自分の参加を確認してから変換する
      if (joinflag == 1) {
        if (s.equals("T")) {
          ondo = Double.parseDouble(dat[0]);
        } else {
          ondo = Double.parseDouble(dat[1]);
        }
      } else {
        ondo = 0;
      }
      current = ondo;
      // スタイダに値をセット
      sl.setValue((int)current);
      if (s.equals("T")) {
        sl.setMaximum(50);
        sl.setForeground(Color.orange);	// Windows の場合はほかの色
      } else {
        sl.setMaximum(90);
        sl.setForeground(Color.cyan);	// Windows の場合はほかの色
      }
      // 描画更新
      mc.repaint();
      // sl.repaint();
      try {
        // １秒更新
        Thread.sleep(1000);
      }
      catch(InterruptedException ex) {
      }
      flag = 1;
    }
  }
  
  // ７セグメント表示部
  public static class DigCanvas extends Canvas {
    public Image image[] = new Image[13];
    public static Image lamp;
    int i;
    // ディジタル画像用意
    DigCanvas(int x, int y) {
      //Toolkit toolkit = getToolkit();
      ImageComponent2 imgConpo = new ImageComponent2();
      for (i = 0; i < 10; i++) {
        String gif = Integer.toString(i) + "FDG.GIF";
        image[i] = imgConpo.getImageData(gif, dir);
      }
      // 小数点(明るい)
      image[i] = imgConpo.getImageData("PFDG.GIF", dir);       // o
      // 小数点(暗い)
      image[i + 1] = imgConpo.getImageData("DFDG.GIF", dir);   // .
      image[i + 2] = imgConpo.getImageData("MFDG.GIF", dir);   // -
      setSize(x, y);
    }

    // ディジタル温度表示
    public void paint(Graphics g) {
      // グラデーション
      Graphics2D g2 = (Graphics2D) g;
      GradientPaint gp = new GradientPaint(0, 25, Color.lightGray, 1, 8, Color.blue, true);
      g2.setPaint(gp);
      int locate = 0;
      int loc = 0;
      // データより小数点を判別
      String SS = null;
      String S1 = ".";
      if (flag == 1) {
        if (ondo < 10.0) {
          g.drawImage(image[0], (locate * 10) + 5, 16, this);
          locate++;
        }
        // 小数点の探出
        String ondoString = Double.toString(ondo);
        for (i = 0; i < ondoString.length(); i++) {
          // 小数点の確認
          SS = ondoString.substring(i, i + 1);
          if (S1.equals(SS)) {
            loc = 10;
          } else {
            loc = Integer.parseInt(SS);
          }
          // 小数点処理
          if (loc == 10) {
            if (ledflag == 2) {
              // 明るい小数点
              g.drawImage(image[loc], (locate * 14) + 5, 16, this);
            } else {
              // 暗い小数点
              g.drawImage(image[loc + 1], (locate * 14) + 5, 16, this);
            }
          } else {
            g.drawImage(image[loc], (locate * 14) + 5, 16, this);
          }
          locate++;
        }
        if (joinflag == 0) {
          for (locate = 0; locate < 4; locate++) {
            g.drawImage(image[12], (locate * 14) + 5, 16, this);
          }
        }
      }
      // 透明度処理
      Composite comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5F);
      g2.setComposite(comp);
      g2.fillRect(0, 0, 100, 200);
    }
    public void update(Graphics g) {
      paint(g);
    }
  }
  
  // ラジオ・ボタンのカスタマイズ
  public static class PushButton {
    public PushButton() {
      String description = "selector";
      String text = "";
      Image img;
      ImageComponent3 imgConpo = new ImageComponent3();
      radio1 = new JRadioButton(text, new ImageIcon(imgConpo.getImageData3("rb.gif", dir)), true);
      radio1.setPressedIcon(new ImageIcon(imgConpo.getImageData3("rbp.gif", dir)));
      radio1.setRolloverIcon(new ImageIcon(imgConpo.getImageData3("rbr.gif", dir)));
      radio1.setRolloverSelectedIcon(new ImageIcon(imgConpo.getImageData3("rbs.gif", dir)));
      radio1.setSelectedIcon(new ImageIcon(imgConpo.getImageData3("rbs.gif", dir)));
      radio1.setFocusPainted(false);
      radio1.setBorderPainted(false);
      radio1.setContentAreaFilled(false);
      radio1.setMargin(new Insets(0, 0, 0, 0));
    }
  }
  
  // ラジオ・ボタンのカスタマイズ
  public static class PushButton2 {
    public PushButton2() {
      String description = "selector";
      String text = "";
      ImageComponent3 imgConpo = new ImageComponent3();
      radio2 = new JRadioButton(text, new ImageIcon(imgConpo.getImageData3("rb.gif", dir)), true);
      radio2.setPressedIcon(new ImageIcon(imgConpo.getImageData3("rbp.gif", dir)));
      radio2.setRolloverIcon(new ImageIcon(imgConpo.getImageData3("rbr.gif", dir)));
      radio2.setRolloverSelectedIcon(new ImageIcon(imgConpo.getImageData3("rbs.gif", dir)));
      radio2.setSelectedIcon(new ImageIcon(imgConpo.getImageData3("rbs.gif", dir)));
      radio2.setFocusPainted(false);
      radio2.setBorderPainted(false);
      radio2.setContentAreaFilled(false);
      radio2.setMargin(new Insets(0, 0, 0, 0));
	}
  }
}

//EOF

