/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package de.nplusc.izc.iZpl.GUI;

import com.sun.awt.AWTUtilities;
import de.nplusc.izc.tools.UiToolz.ComponentMover;
import de.nplusc.izc.tools.UiToolz.HoloJPanel;
import de.nplusc.izc.tools.UiToolz.HoloSliderUi;
import de.nplusc.izc.tools.UiToolz.IZSkinFile;
import de.nplusc.izc.tools.baseTools.Messagers;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JSlider;

/**
 *
 * @author LH
 */
public class PlayListManagingSkinnable extends JFrame implements MouseMotionListener , MouseListener
{
    
    public static final int BUTTON_NONE_ID=0;
    public static final int BUTTON_IXX_ID=1;
    public static final int BUTTON_MIN_ID=2;
    public static final int BUTTON_HIDE_ID=3;
    public static final int BUTTON_RELOAD_ID=4;
    public static final int BUTTON_FORCE_ID=5;
    
    public static final boolean STATE_HILIT=false;
    public static final boolean STATE_CLICKED=!STATE_HILIT;
    public static final Color TransBgColor = new Color(0, 0, 0, 0);
    
    private String bdir;
    private IZSkinFile sf;
    private int h,w;
    private ComponentMover m;
    private JSlider s;
    private Color txc = Color.BLACK;
    
    private String[] titles;
    
    private Image paintme,background,buttonIxxClicked,buttonIxxHilit,buttonMinClicked,buttonMinHilit,buttonHideClicked,buttonHideHilit,
                    buttonReloadHilit,buttonReloadClicked,buttonForceClicked,buttonForceHilit,sliderknob;
    private HoloJPanel PA;
    //definieren die heißen zonen....
    private Polygon buttonIxx,buttonMin,buttonHide,buttonReload,buttonForce;
    private int tablewidth=500,tableheight=500,lineheight=15;//defaultwerte wenn exception fliegt
    private int defaultlc=0x000000,hilitcolor=0xffff00,selected=0xff7700;
    private int lc;//dynamish generiert im konstruktor; lazyness...
    JLabel[] th;//datenjonglage die 2.
    
    JLabel[][] tab;//datenjonglage...
    public PlayListManagingSkinnable(IZSkinFile f,String baseDir)
    {
        bdir=baseDir;
        HashMap<String,String> ed=f.getElementData();
        HashMap ep = f.getElementPositions();
        sf=f;
        //separate exceptions sind gewollt um mitzuteilen welcher key fail'd
        try{
            tablewidth = Integer.valueOf(ed.get("tablewidth"));
        }
        catch(NumberFormatException lickme)
        {
            Messagers.SingleLineMsg("Error in SkinFile", "ungültiger Wert für tablewidth");
        }
        try{
            tableheight = Integer.valueOf(ed.get("tableheight"));
        }
        catch(NumberFormatException lickme)
        {
            Messagers.SingleLineMsg("Error in SkinFile", "ungültiger Wert für tableheight");
        }
        try{
            lineheight = Integer.valueOf(ed.get("lineheight"));
        }
        catch(NumberFormatException lickme)
        {
            Messagers.SingleLineMsg("Error in SkinFile", "ungültiger Wert für lineheight");
        }
        setUndecorated(true);
        boolean tp = AWTUtilities.isTranslucencySupported(AWTUtilities.Translucency.PERPIXEL_TRANSLUCENT);
        if(tp)
        {
            AWTUtilities.setWindowOpaque(this, false);//freischalten von irregularShapes
            //AWTUtilities.
        }
        background = loadImageAux(ed.get("backgroundlayer"));
        paintme = loadImageAux(ed.get("backgroundlayer"));//background ist default deshalb doppeltgemoppelt; auf paintme wird später rumgepinselt
        buttonIxxHilit = loadImageAux(ed.get("button_IXX_hilit"));
        buttonIxxClicked = loadImageAux(ed.get("button_IXX_clicked"));
        buttonMinHilit = loadImageAux(ed.get("button_min_hilit"));;
        buttonMinClicked = loadImageAux(ed.get("button_min_clicked"));
        buttonHideClicked = loadImageAux(ed.get("button_hide_clicked"));
        buttonHideHilit = loadImageAux(ed.get("button_hide_hilit"));
        buttonReloadClicked = loadImageAux(ed.get("button_reload_clicked"));;
        buttonReloadHilit = loadImageAux(ed.get("button_reload_hilit"));
        buttonForceClicked = loadImageAux(ed.get("button_force_clicked"));
        buttonForceHilit = loadImageAux(ed.get("button_force_hilit"));
        sliderknob=loadImageAux(ed.get("scrollbarknob"));
        
        
        while(background.getHeight(null)<=0);  //absicern dass image geladen...
        while(paintme.getHeight(null)<=0);  //absicern dass image geladen...
        h = background.getHeight(null);
        w = background.getWidth(null);
        setSize(w, h);
        PA= new HoloJPanel();
        PA.setSize(w,h);
        PA.setOpaque(false);
        //int[] ixb = ep.get("button_IXX");
        //paintme.getGraphics().drawImage(buttonIxxHilit, ixb[0], ixb[1], null);
        PA.setdrawIMG(paintme);
        add(PA);
        System.out.println("skindim="+w+"|"+h);
        Container cp = getContentPane();
        cp.setLayout(null);
        while(buttonIxxHilit.getHeight(null)<=0);
        while(buttonIxxClicked.getHeight(null)<=0);
        while(buttonMinHilit.getHeight(null)<=0);
        while(buttonMinClicked.getHeight(null)<=0);
        while(buttonHideClicked.getHeight(null)<=0);
        while(buttonHideHilit.getHeight(null)<=0);
        while(buttonReloadClicked.getHeight(null)<=0);
        while(buttonReloadHilit.getHeight(null)<=0);
        while(buttonForceClicked.getHeight(null)<=0);
        while(buttonForceHilit.getHeight(null)<=0);
        while(sliderknob.getHeight(null)<=0); //absicern dass image geladen...
        PA.addMouseListener(this);
        PA.addMouseMotionListener(this);
        HoloJPanel p = new HoloJPanel();
        PA.setLayout(null);
        //BufferedImage b = new BufferedImage(700, 30, BufferedImage.TYPE_4BYTE_ABGR);
        //b.getGraphics().setColor(Color.BLACK);
        //b.getGraphics().fillRect(0, 0, 700, 30);
        p.setdrawIMG(background);
        p.setSize(700,30);//TODO: set title bar size as config
        PA.add(p);
        m=new ComponentMover(PlayListManagingSkinnable.class);
        m.registerComponent(p);
        //ermöglichen der buttonerkennung...
        boolean buttondetected = true;
        buttonIxx = new Polygon();
        int i = 1;
        while (buttondetected)
        {
            ArrayList<Integer> ixb = (ArrayList<Integer>) ep.get("button_IXX");
            List<Integer> data = (List<Integer>) ep.get("button_IXX_point_" + i);
            buttonIxx.addPoint(data.get(0) + ixb.get(0), data.get(1) + ixb.get(1));
            i++;
            buttondetected = ep.containsKey("button_IXX_point_" + i);
        }
        buttondetected = true;
        buttonMin = new Polygon();
        i = 1;
        while (buttondetected)
        {
            ArrayList<Integer> ixb = (ArrayList<Integer>) ep.get("button_min");
            List<Integer> data = (List<Integer>) ep.get("button_min_point_" + i);
            buttonMin.addPoint(data.get(0) + ixb.get(0), data.get(1) + ixb.get(1));
            i++;
            buttondetected = ep.containsKey("button_min_point_" + i);
        }
        buttondetected = true;
        buttonHide = new Polygon();
        i = 1;
        while (buttondetected)
        {
            ArrayList<Integer> ixb = (ArrayList<Integer>) ep.get("button_hide");
            List<Integer> data = (List<Integer>) ep.get("button_hide_point_" + i);
            buttonHide.addPoint(data.get(0) + ixb.get(0), data.get(1) + ixb.get(1));
            i++;
            buttondetected = ep.containsKey("button_hide_point_" + i);
        }
        buttondetected = true;
        buttonForce = new Polygon();
        i = 1;
        while (buttondetected)
        {
            ArrayList<Integer> ixb = (ArrayList<Integer>) ep.get("button_force");
            List<Integer> data = (List<Integer>) ep.get("button_force_point_" + i);
            buttonForce.addPoint(data.get(0) + ixb.get(0), data.get(1) + ixb.get(1));
            i++;
            buttondetected = ep.containsKey("button_force_point_" + i);
        }
        buttondetected = true;
        buttonReload = new Polygon();
        i = 1;
        while (buttondetected)
        {
            ArrayList<Integer> ixb = (ArrayList<Integer>) ep.get("button_reload");
            List<Integer> data = (List<Integer>) ep.get("button_reload_point_" + i);
            buttonReload.addPoint(data.get(0) + ixb.get(0), data.get(1) + ixb.get(1));
            i++;
            buttondetected = ep.containsKey("button_reload_point_" + i);
        }
        //generate_table
        int l2p=tablewidth-160,l3p=tablewidth-80;
        PA.setLayout(null);
        lc = tableheight/lineheight-1;//oberste zeile=header
        ArrayList<Integer> tbb = (ArrayList<Integer>) ep.get("tablestart");
        System.out.println("tw(l2p,l3p),th,lc,lh|tbb[0],tbb[1]=>"+tablewidth+"("+l2p+","+l3p+"),"+tableheight+","+lc+","+lineheight+"|"+tbb.get(0)+","+tbb.get(1));
        th = new JLabel[3];
        th[0] = new JLabel("Element-Titel");
        th[0].setForeground(txc);
        th[0].setBounds(tbb.get(0), tbb.get(1), l2p, lineheight);
        th[1] = new JLabel("# to play");
        th[1].setForeground(txc);
        th[1].setBounds(tbb.get(0)+l2p, tbb.get(1), 80, lineheight);
        th[2] = new JLabel("# Played");
        th[2].setForeground(txc);
        th[2].setBounds(tbb.get(0)+l3p, tbb.get(1), 80, lineheight);
        PA.add(th[0]);
        PA.add(th[1]);
        PA.add(th[2]);
        tab = new JLabel[lc][3];
        for (int ix=0;ix<lc;ix++)
        {
            JLabel[] cnt = tab[ix];
            cnt[0] = new JLabel("###################################################<><>");  //DEBUG_PLACEHOLDERS
            cnt[0].setBounds(tbb.get(0), tbb.get(1)+(lineheight*(ix+1)), l2p, lineheight);
            cnt[0].setForeground(txc);
            PA.add(cnt[0]);
            cnt[1] = new JLabel("########>>>");
            cnt[1].setBounds(tbb.get(0)+l2p, tbb.get(1)+(lineheight*(ix+1)), 80, lineheight);
            cnt[1].setForeground(txc);
            PA.add(cnt[1]);
            cnt[2] = new JLabel("<<<########");
            cnt[2].setBounds(tbb.get(0)+l3p, tbb.get(1)+(lineheight*(ix+1)), 80, lineheight);
            cnt[2].setForeground(txc);
            PA.add(cnt[2]);
        }
        
        s = new JSlider(0,100);
        ArrayList<Integer> sbb = (ArrayList<Integer>) ep.get("scrollbarstart");
        s.setBounds(sbb.get(0), sbb.get(1), 20, tableheight);
        HoloSliderUi ui = new HoloSliderUi(s,sliderknob);
        ui.po=true;
        s.setUI(ui);
        s.setOpaque(false);
        s.setOrientation(JSlider.VERTICAL);
        s.setMinimum(0);
        s.setMaximum(100);
        s.setInverted(true);
        s.addMouseMotionListener(this);
        s.addMouseListener(this);
        PA.add(s);
        reloadWorker();
    }
    
    
    public void reloadWorker()
    {
        PlayListManagingBackend.refreshKeyList();
        titles=PlayListManagingBackend.getTrackTitles();
        s.setVisible(titles.length>lc);//deaktivieren wenn weniger zeilen als LC; mehr wenn aktiviert...
        s.setMaximum(((titles.length-lc)<0?0:titles.length-lc));
        s.setValue(0);//an anfang kalibrieren...
        for (int i = 0; i < lc; i++)//kontrolliertes ausIxxen der tabelle zur initialisierung; man braucht keine Debugzeilen am ende wenn weniger Zeilen als LIneCount....
        {
            JLabel[] l = tab[i];
            for (int j = 0; j < l.length; j++)
            {
                l[j].setText("");
            }
        }
        for (int i = 0; i < titles.length; i++)
        {
            if(i<lc)
            {
            JLabel[] l = tab[i];
            String t = titles[i];
            l[0].setText(t);
            l[1].setText(PlayListManagingBackend.getTargetPlayCount(i)+"");
            l[2].setText(PlayListManagingBackend.getPlayCount(i)+"");
            }
            else
            {
                break;
            }
        }
    }
    
    
    
    @Override
    public void mouseDragged(MouseEvent e)
    {
        tickTable(s.getValue());
    }
    
    public void tickTable(int bv)
    {
        for (int i = 0; i < lc; i++)
        {
            int ir = i+bv;
            JLabel[] l = tab[i];
            String t = titles[ir];
            l[0].setText(t);
            l[1].setText(PlayListManagingBackend.getTargetPlayCount(ir)+"");
            l[2].setText(PlayListManagingBackend.getPlayCount(ir)+"");
        }
        
    }
    //scrollbarstart -> obere linke ecke des sliders; Höhe = tableheight
     //scrollbarknob
    
    public void tickGUI(int affectedButton,boolean state)
    {
        HashMap ep = sf.getElementPositions();
        Graphics g = paintme.getGraphics();
        ((Graphics2D)g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC));//WIXTIX!!!!
        g.drawImage(background, 0, 0, null);
        if(affectedButton==BUTTON_IXX_ID)
        {
            ArrayList<Integer> ixb= (ArrayList<Integer>) ep.get("button_IXX");
            if(state==STATE_HILIT)
            {
                g.drawImage(buttonIxxHilit, ixb.get(0), ixb.get(1), null);
            }
            else
            {
               g.drawImage(buttonIxxClicked, ixb.get(0), ixb.get(1), null);
            }
        }
        if(affectedButton==BUTTON_MIN_ID)
        {
            ArrayList<Integer> ixb= (ArrayList<Integer>) ep.get("button_min");
            if(state==STATE_HILIT)
            {
                g.drawImage(buttonMinHilit, ixb.get(0), ixb.get(1), null);
            }
            else
            {
               g.drawImage(buttonMinClicked, ixb.get(0), ixb.get(1), null);
            }
        }
        if(affectedButton==BUTTON_HIDE_ID)
        {
            ArrayList<Integer> ixb= (ArrayList<Integer>) ep.get("button_hide");
            if(state==STATE_HILIT)
            {
                g.drawImage(buttonHideHilit, ixb.get(0), ixb.get(1), null);
            }
            else
            {
               g.drawImage(buttonHideClicked, ixb.get(0), ixb.get(1), null);
            }
        }
        if(affectedButton==BUTTON_RELOAD_ID)
        {
            ArrayList<Integer> ixb= (ArrayList<Integer>) ep.get("button_reload");
            if(state==STATE_HILIT)
            {
                g.drawImage(buttonReloadHilit, ixb.get(0), ixb.get(1), null);
            }
            else
            {
               g.drawImage(buttonReloadClicked, ixb.get(0), ixb.get(1), null);
            }
        }
        if(affectedButton==BUTTON_FORCE_ID)
        {
            ArrayList<Integer> ixb= (ArrayList<Integer>) ep.get("button_force");
            if(state==STATE_HILIT)
            {
                g.drawImage(buttonForceHilit, ixb.get(0), ixb.get(1), null);
            }
            else
            {
               g.drawImage(buttonForceClicked, ixb.get(0), ixb.get(1), null);
            }
        }
        repaint();
        //System.out.println("NOP");
    }


    
    
    
    
    private Image loadImageAux(String filename)
    {
        try
        {
            return ImageIO.read(new File(bdir+"\\"+filename));
        }
        catch (IOException ex)
        {
            ex.printStackTrace();
        }
        return null;
    }

    
    
    


    @Override
    public void mouseMoved(MouseEvent e)
    {
        Point p = e.getPoint();
        if(buttonIxx.contains(p))
        {
            tickGUI(BUTTON_IXX_ID, STATE_HILIT);
        }
        else
        {
            if(buttonMin.contains(p))
            {
                 tickGUI(BUTTON_MIN_ID, STATE_HILIT);
            }
            else
            {
                if(buttonHide.contains(p))
                {
                     tickGUI(BUTTON_HIDE_ID, STATE_HILIT);
                }
                else
                {
                    if(buttonReload.contains(p))
                    {
                         tickGUI(BUTTON_RELOAD_ID, STATE_HILIT);
                    }
                    else
                    {
                        if(buttonForce.contains(p))
                        {
                            tickGUI(BUTTON_FORCE_ID, STATE_HILIT);
                        }
                        else
                        {
                            tickGUI(BUTTON_NONE_ID, STATE_HILIT);
                        }
                    }
                }
            }
            
        }
               
    }
    
    Point pp = new Point();
    
    @Override
    public void mouseClicked(MouseEvent e)
    {
        if(e.getSource()==s)
        {
            tickTable(s.getValue());
            return;
        }
        pp=e.getPoint();
        
    }

    @Override
    public void mousePressed(MouseEvent e)
    {
        if(e.getSource()==s)
        {
            tickTable(s.getValue());
            return;
        }
        pp=e.getPoint();
        Point p = e.getPoint();
        if((e.getButton()&MouseEvent.BUTTON2)!=0)
        {
            return; //hook für Kontextmenü :P
        }
        if(buttonIxx.contains(p))
        {
            tickGUI(BUTTON_IXX_ID, STATE_CLICKED);
        }
        else
        {
            if(buttonMin.contains(p))
            {
                 tickGUI(BUTTON_MIN_ID, STATE_CLICKED);
            }
            else
            {
                if(buttonHide.contains(p))
                {
                     tickGUI(BUTTON_HIDE_ID, STATE_CLICKED);
                }
                else
                {
                    if(buttonReload.contains(p))
                    {
                         tickGUI(BUTTON_RELOAD_ID, STATE_CLICKED);
                    }
                    else
                    {
                        if(buttonForce.contains(p))
                        {
                            tickGUI(BUTTON_FORCE_ID, STATE_CLICKED);
                        }
                        else
                        {
                            tickGUI(BUTTON_NONE_ID, STATE_CLICKED);
                        }
                    }
                }
            }
        }
    }

    @Override
    public void mouseReleased(MouseEvent e)
    {
        if((e.getButton()&MouseEvent.BUTTON2)!=0)
        {
            return; //hook für Kontextmenü :P
        }
        Point p = e.getPoint();
        if(buttonIxx.contains(p)&&buttonIxx.contains(pp))
        {
            System.exit(0);
        }
        else
        {
            if(buttonMin.contains(p)&&buttonMin.contains(pp))
            {

            }
            else
            {
                if(buttonHide.contains(p)&&buttonMin.contains(pp))
                {

                }
                else
                {
                    if(buttonReload.contains(p)&&buttonMin.contains(pp))
                    {

                    }
                    else
                    {
                        if(buttonForce.contains(p)&&buttonMin.contains(pp))
                        {

                        }
                        else
                        {

                        }
                    }
                }
            }
            
        }
    }

    @Override
    public void mouseEntered(MouseEvent e)
    {
        
    }

    @Override
    public void mouseExited(MouseEvent e)
    {
        
    }
    
    
    
}


/**
 * Pfad zu skins: iZplaylist-dir/skins/*.iZskin; 
 * 
 * Definition Skin-metadata
 * //namen der objekte;
 * //backgroundlayer -> basis-oberfläche;GFX
 * //tablestart -> obere linke ecke der labels
 * //tablewidth -> breite der labels
 * //tableheight -> höhe der tabelle
 * //scrollbarstart -> obere linke ecke des sliders; Höhe = tableheight
 * //scrollbarknob -> nippel des sliders;GFX
 * //lineheight -> höhe einer einzelnen Zeile -> bestimmt Zeilenzahl
 * //mode=_clicked/_hilit
 * //button_IXX<_mode> -> schließenschaltfläche;GFX
 * //button_min<_mode> -> Minimierenbutton;GFX
 * //button_reload<_mode> -> neuladen-button;GFX
 * //button_force<_mode> -> erzwingen-button;GFX
 * //button_hide<_mode> -> ausblenden-button;GFX
 * //button_<buttonname> -> basepoint des buttons
 * 
 * //button_<buttonname>_point_N = Polygonpunkt der Selektierungszone relativ zu seinem nullpunkt...
 * 
 * 
 */
