package cs437.som.visualization;

import cs437.som.SelfOrganizingMap;
import cs437.som.Dimension;

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;

/**
 * Visualization for SOM with a 3-dimensional input.
 * Adapted from 2D plotter. Instead of using position to map neuron weights, it uses color.
 */
public class SOM3dPlotter extends JFrame {
    private static final long serialVersionUID = 0L;
    
    private static final int WIDTH = 500;
    private static final int HEIGHT = 500;
    private SelfOrganizingMap map = null;
    private Dimension dims;
    private BufferedImage img;

    /**
     * Create and setup a dot plot for a 3D input SOM.
     * @param map The SOM to plot.
     */
    public SOM3dPlotter(SelfOrganizingMap map) {
        super("SOM Plot");

        if (map.getInputLength() != 3) throw new IllegalArgumentException("SOM does not map 3d inputs");

        this.map = map;

        dims = this.map.getGridSize();
        img = new BufferedImage(dims.x, dims.y, BufferedImage.TYPE_INT_ARGB);

        setSize(WIDTH, HEIGHT);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        createBufferStrategy(2);
    }

    /**
     * Draw the current weights of the SOM's neurons.
     */
    public void draw() {
        Graphics g = getBufferStrategy().getDrawGraphics();

        int neuronCount = map.getNeuronCount();
        int[] pts = new int[neuronCount];

        for (int i = 0; i < neuronCount; i++) {
            pts[i] = 0xFF000000;
            pts[i] += (int)(map.getWeight(i,0)*255)<<16;
            pts[i] += (int)(map.getWeight(i,1)*255)<<8;
            pts[i] += (int)(map.getWeight(i,2)*255);
        }

        img.setRGB(0,0, dims.x, dims.y, pts, 0, dims.x);

        g.drawImage(img.getScaledInstance(WIDTH, HEIGHT, Image.SCALE_DEFAULT), 0, 0, null);

        getBufferStrategy().show();
    }

    @Override
    public String toString() {
        return "SOM3dPlotter{map=" + map + '}';
    }
}

@@ -502,32 +502,151 @@
 t HEIGHT = 500;%0A
+    static final int MAX_ALPHA = 0xFF000000;%0A    static final int BYTE_MAX = 255;%0A    static final int BYTE_WIDTH = 8;%0A
     private Self
@@ -659,19 +659,19 @@
 zingMap 
-map
+som
  = null;
@@ -729,16 +729,49 @@
 age img;
+%0A    private int neuronCount = 0;
 %0A%0A    /*
@@ -985,16 +985,30 @@
 () != 3)
+ %7B%0A           
  throw n
@@ -1065,16 +1065,26 @@
 nputs%22);
+%0A        %7D
 %0A%0A      
@@ -1089,24 +1089,19 @@
     
-this.map
+som
  = map;%0A
 %0A   
@@ -1096,17 +1096,16 @@
  = map;%0A
-%0A
         
@@ -1115,16 +1115,11 @@
 s = 
-this.map
+som
 .get
@@ -1126,24 +1126,58 @@
 GridSize();%0A
+        neuronCount = dims.area;%0A%0A
         img 
@@ -1550,56 +1550,8 @@
 );%0A%0A
-        int neuronCount = map.getNeuronCount();%0A
     
@@ -1658,26 +1658,25 @@
 ts%5Bi%5D = 
-0xFF000000
+MAX_ALPHA
 ;%0A      
@@ -1684,33 +1684,33 @@
      pts%5Bi%5D 
-+
+%7C
 = (int)(
 map.getWeigh
@@ -1689,35 +1689,35 @@
 pts%5Bi%5D %7C= (int)(
-map
+som
 .getWeight(i,0)*
@@ -1717,19 +1717,43 @@
 t(i,
+ 
 0)
-*255)%3C%3C16
+ * BYTE_MAX) %3C%3C (2 * BYTE_WIDTH)
 ;%0A  
@@ -1765,33 +1765,33 @@
      pts%5Bi%5D 
-+
+%7C
 = (int)(
 map.getWeigh
@@ -1770,35 +1770,35 @@
 pts%5Bi%5D %7C= (int)(
-map
+som
 .getWeight(i,1)*
@@ -1798,18 +1798,37 @@
 t(i,
+ 
 1)
-*255)%3C%3C8
+ * BYTE_MAX) %3C%3C BYTE_WIDTH
 ;%0A  
@@ -1848,17 +1848,17 @@
 %5Bi%5D 
-+
+%7C
 = (int)(
 map.
@@ -1853,19 +1853,19 @@
 = (int)(
-map
+som
 .getWeig
@@ -1873,14 +1873,22 @@
 t(i,
+ 
 2)
-*255
+ * BYTE_MAX
 );%0A 
@@ -2169,19 +2169,19 @@
 ter%7B
-map
+som
 =%22 + 
-map
+som
  + '

Use bit-or for bit manipulations.