package turgen;

import turgen.generator.SignalGenerator;
import java.util.*;

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

import turgen.generator.ProgressSource;


 /**Progress sources synchronization
 *
 */
 
public class ProgressSynchronizer {
    
    /**Panel-Source mapping*/
    public HashMap panelMap;
    /**Source-Panel mapping*/
    public HashMap sourcesMap;
    /**Mapa of output files*/
    private final HashSet outFileSet;
    /**Universal listener for STOP buttons*/
    private final ActionListener stopper;
    
    
    
    
    /** New instance*/
    public ProgressSynchronizer() {
        
        outFileSet = new HashSet();
        
        panelMap = new HashMap();
        sourcesMap=new HashMap();
        
        stopper = new ActionListener() {
            public synchronized void actionPerformed(ActionEvent e) {
                GeneratorPanel p = (GeneratorPanel)(((Component)(e.getSource())).getParent());
                ProgressSource g = (ProgressSource)panelMap.get(p);
                
                if (e.getActionCommand()!=null && e.getActionCommand().equals("Resume")) {
                    g.unPause();
                    p.btnResume.setEnabled(false);
                    return;
                }
                
                int t=SignalGenerator.CANCEL_ONE;
                if (e.getActionCommand()!=null && e.getActionCommand().equals("STOP ALL")) t=SignalGenerator.CANCEL_ALL;
                
                p.btnStop.setEnabled(false);
                if (t==SignalGenerator.CANCEL_ALL) {
                    p.btnStopAll.setEnabled(false);
                }
                
                p.progressThread.interrupt();
                g.cancelOperation(t);
            }
        };
    }
    
    /** Playlist item registration
     *  @param g Progress source that register that item
     *  @return true success, false failure
     */
    synchronized public boolean registerProgress(ProgressSource g,Thread t) {
        
        /*If progress source has output file, it has to be registred*/
        if(g.getOutputFile()!=null) {
            
            if (outFileSet.contains(g.getOutputFile())==true) {
                return false;
            }
            outFileSet.add(new String(g.getOutputFile()));
        }
        
        /*Create new panel and add it to TurgenFrame*/
        GeneratorPanel p = new GeneratorPanel(g,t);
        p.addListener(stopper);
        
        Turgen.dlm.frmTurgen.getProgressPanel().add(p);
        p.revalidate();
        panelMap.put(p, g); 
        sourcesMap.put(g,p);
        return true;
    }
    
    /** Item unregistration
     *  @param g Progress source
     */
    
    synchronized public void unregisterProgress(ProgressSource g) {
        
        /*Unregister output file if necessary*/
        if (g.getOutputFile()!=null) {
            outFileSet.remove(g.getOutputFile());
        }
        
        /*Remove panel*/
        GeneratorPanel p = (GeneratorPanel)sourcesMap.get(g);
        panelMap.remove(p);
        sourcesMap.remove(g);
        JComponent cp = (JComponent)p.getParent();
        cp.remove(p);
        cp.revalidate();
        cp.repaint();
        
        /* If progress source was not part of sequence, error
         * message should be shown if needed
         */
         
        if (g.isPartOfSequence()==false) {
            String s = g.getErrorMessage();
            if (s!=null) {
                ParallelGUIUpdater.showMessage(s);
            }
        }
        
    }

    public void pauseProgress(ProgressSource s) {
        GeneratorPanel p = (GeneratorPanel)sourcesMap.get(s);
        p.btnResume.setEnabled(true);
    }
    
    
    
}
/** Panel for monitoring progress source */
    class GeneratorPanel extends JPanel {
        /**Reference to playlist item*/
        ProgressSource source;
        JProgressBar progress;
        JButton btnStop;
        JButton btnStopAll=null;
        JButton btnResume=null;
        Thread progressThread;
        
        /**New instance
         * 
         */
        public GeneratorPanel(ProgressSource src,Thread t) {
            /*Dimensions*/
            super(new FlowLayout(FlowLayout.LEFT,1,0));
            progressThread=t;
            progress=new JProgressBar(JProgressBar.HORIZONTAL,0,100);
            progress.setStringPainted(true);
            progress.setPreferredSize(new Dimension(80,20));
            
            /*Label*/
            source=src;
            String s1;
            String s2=source.getInputFile();
            
            int i=s2.lastIndexOf(System.getProperty("file.separator"));
            if (i>0) s1=s2.substring(i+1,s2.length()); else s1=s2;
            
            /*STOP,STOP ALL buttons*/
            this.add(new JLabel(s1));
            this.add(progress);
            btnStop = new JButton("STOP");
            btnStop.setMargin(new java.awt.Insets(1, 1, 1, 1));
            this.add(btnStop);
            
            if (source.isPartOfSequence()==true) {
                btnStopAll = new JButton("STOP ALL");
                btnStopAll.setMargin(new java.awt.Insets(1, 1, 1, 1));
                this.add(btnStopAll);
            }
            
            if (source.isPausable()==true) {
                btnResume = new JButton("Resume");
                btnResume.setMargin(new java.awt.Insets(1, 1, 1, 1));
                this.add(btnResume);
                btnResume.setEnabled(false);
            }
        }
        
        /** Add Button listener to button
         *  @param listener Posluchac
         */
        public void addListener(ActionListener listener) {
            this.btnStop.addActionListener(listener);
            if (btnStopAll!=null) this.btnStopAll.addActionListener(listener);
            if (btnResume!=null) this.btnResume.addActionListener(listener);
        }
        
        
    }