package com.greinet.tvtotalripper.ui;

import com.greinet.tvtotalripper.download.DownloadTask;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;

/**
 * A download panel to show the current downloads
 */
public class DownloadRipperPanel implements PropertyChangeListener{
    
    /** The JPanel for download task visualization */
    private final JPanel panel;
    /** The JList for the downloads */
    private JList<DownloadTask> listTasks;
    /** The ListModel for the DownloadTasks */
    private final DefaultListModel<DownloadTask> listModel;
    /** The text field for the currently selected task */
    private JTextField textSelectedTask;
    /** The JLabel for the DownloadTask count */
    private final JLabel labelTaskCount;
    /** The list of download tasks */
    private final List<DownloadTask> downloadTasks;
    /** The information panel for the currently selected task */
    private DownloadTaskInformationPanel infoPanel;
    
    private final ExecutorService threadPool = Executors.newFixedThreadPool(5);
    
    /**
     * Create a download panel
     */
    public DownloadRipperPanel(){
        
        downloadTasks = new ArrayList<>();
        
        panel = new JPanel();
        panel.setLayout(new GridBagLayout());
        
        GridBagConstraints c = new GridBagConstraints();
        
        c.gridx = 0;
        c.gridy = 0;
        c.gridwidth = 5;
        c.fill = GridBagConstraints.BOTH;
        c.weightx = 0.5;
        textSelectedTask = new JTextField();
        textSelectedTask.setEditable(false);
        panel.add(textSelectedTask, c);
        
        
        listModel = new DefaultListModel<>();
        listTasks = new JList<>(listModel);
        listTasks.setSelectedIndex(ListSelectionModel.SINGLE_SELECTION);
        JScrollPane scrollPane = new JScrollPane();
        scrollPane.setViewportView(listTasks);
        listTasks.setLayoutOrientation(JList.VERTICAL);
        
        c.gridx = 0;
        c.gridy = 1;
        c.gridwidth = 5;
        c.gridheight = 5;
        c.weightx = 0.5;
        panel.add(scrollPane, c);
        
        infoPanel = new DownloadTaskInformationPanel();
        c.gridx = 5;
        c.gridy = 0;
        c.gridwidth = 5;
        c.weightx = 0.5;
        c.fill = GridBagConstraints.BOTH;
        panel.add(infoPanel, c);
        
        listTasks.addListSelectionListener((ListSelectionEvent e) -> {
            if(listTasks.getSelectedValue()!=null){
                textSelectedTask.setText(listTasks.getSelectedValue().toString());
                infoPanel.setInformation(listTasks.getSelectedValue());
                infoPanel.selectedDownloadTask = listTasks.getSelectedValue();
            }
        });
        
        
        labelTaskCount = new JLabel(Integer.toString(listTasks.getModel().getSize()));
        labelTaskCount.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
        
        c.gridx = 4;
        c.gridy = 6;
        c.gridwidth = 1;
        c.gridheight = 1;
        c.fill = GridBagConstraints.NONE;
        c.anchor = GridBagConstraints.EAST;
        panel.add(labelTaskCount, c);
    }
    
    /**
     * Get the JPanel
     * @return the JPanel
     */
    public JPanel getJPanel(){
        return panel;
    }
    
    /**
     * Get the currently selected task
     * @return the selected task
     */
    public DownloadTask getSelectedTask(){
        return listTasks.getSelectedValue();
    }

    /**
     * Add a download task to be executed
     * @param task 
     */
    public void addTask(DownloadTask task){
        downloadTasks.add(task);
        threadPool.submit(task);
        //task.execute();
        listModel.addElement(task);
        updateTaskCount();
        task.addPropertyChangeListener(this);
    }
    

    /**
     * Listen to the property change events and remove a task if the new value is 101
     * @param evt the event parameters
     */
    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        if(evt.getNewValue().equals(101)){
            Optional<DownloadTask> taskToRemove = downloadTasks.stream().filter(t -> Long.toString(t.getEpisodeWrapper().getId()).equals(evt.getPropertyName())).findFirst();
            if(taskToRemove.isPresent()){
                if(listTasks.getSelectedValue() != null && taskToRemove.get().equals(listTasks.getSelectedValue())){
                    infoPanel.clearInformation();
                    textSelectedTask.setText("");
                }
                downloadTasks.remove(taskToRemove.get());
                listModel.removeElement(taskToRemove.get());
                updateTaskCount();
                
            }
        }
        panel.repaint();
    }
    
    /**
     * Update the current task count
     */
    private void updateTaskCount(){
        labelTaskCount.setText(Integer.toString(listTasks.getModel().getSize()));
    }
}
