package turgen.playlist;
import java.util.*;
import javax.swing.table.*;
import java.io.*;
import turgen.*;
import turgen.generator.PulseCrate;

/**Seznam polozek playlistu
 */

public class PlayList extends AbstractTableModel implements Serializable {
    
    /** Seznam polozek*/
    public ArrayList data;
    
    
    /** Nova instance*/
    public PlayList() {
        data = new ArrayList();
    }
    
    /** Prida polozku do playlistu
     *@param r Pridana polozka*/
    public void addItem(AbstractPlayListItem r) {
        data.add(r);
        this.fireTableDataChanged();
    }
    
    /** Vraci polozku z playlistu
     *@param index Index polozky
     *@return Polozka*/
     public AbstractPlayListItem getItem(int index) {
         return (AbstractPlayListItem)data.get(index);
         
     }
     
     /**Odstrani polozku z playlistu
      *@param index Index polozky*/
     public void removeItem(int index) {
         data.remove(index);
         this.fireTableDataChanged();
         
     }
     /**Nahradi polozku playlistu
      *@param index Index nahrazovane polozky
      *@param r Nahrazujici polozka*/
     public void replaceItem(int index, AbstractPlayListItem r) {
         data.set(index,r);
         this.fireTableDataChanged();
     }
     
     /**Posune polozku playlistu nahoru*/
     public boolean moveItemUp(int index) {
         if (index<1) return false;
         Object o = data.get(index-1);
         Object o1 = data.get(index);
         data.set(index-1,o1);
         data.set(index,o);
         this.fireTableRowsUpdated(index-1,index);
         return true;
     }
     
     public boolean moveItemDown(int index) {
         if (index>=data.size()-1) return false;
         Object o = data.get(index);
         Object o1 = data.get(index+1);
         data.set(index+1,o);
         data.set(index,o1);
         this.fireTableRowsUpdated(index,index+1);
         return true;
     }
     
     public Iterator<AbstractPlayListItem> getIterator() {
         return data.iterator();
     }
     
     
     /* IMPLEMENTACE METOD TRIDY ABSTRACTTABLEMODEL */
     /* ======================================================================*/
    
     private static final int COL_COUNT=5;
     
     
     private String[] colNames = {"Input file","Output file","Plugin","Pulses","Details"};
                         
     public int getColumnCount() {
         return PlayList.COL_COUNT;
         
     }
     public int getRowCount() {
         return data.size();
     }
     
     public Object getValueAt(int y,int x) {
         
         AbstractPlayListItem plr = this.getItem(y);
         
         
         switch (x) {
             case 0:{
                 int i=plr.inFile.lastIndexOf(System.getProperty("file.separator"));
                 if (i>0) return plr.inFile.substring(i+1,plr.inFile.length()); else return plr.inFile;
             }
             case 1:{
                int i=plr.outFile.lastIndexOf(System.getProperty("file.separator"));
                if (i>0) return plr.outFile.substring(i+1,plr.outFile.length()); else return plr.outFile;
             }   
             
             case 2: {
                 return Turgen.pluginManager.getPlugin(plr.pluginClass).getName();
             }
             
             case 3: {
                 return plr.pulses;
             }
             case 4: {
                 return plr.toString();
             }
             
             default: return "!";
         }
         
     }
     
     public Class getColumnClass(int index) {
         return String.class;
         
         
     }
     
     public String getColumnName(int index) {
         return colNames[index];
     }
     
     
     /** Save playlist to a file
      * 
      * @param filespec File specifier
      * @throws Exception 
      * 
      * The file format is the following:
      * UTF Characters  - "TS-PLAYLIST"
      * int - Version of the playlist (always 0)
      * int - Total number of playlist items
      * 
      * For each playlist item:
      * UTF Characters - Class name
      * int - Version
      * Playlist item specific data
      * 
      */
     
     public void save(String filespec) throws Exception {
         
         /* Open output file*/
         FileOutputStream fos = new FileOutputStream(filespec);
         BufferedOutputStream bos = new BufferedOutputStream(fos);
         DataOutputStream dos = new DataOutputStream(bos);
         
         /*Write header*/
         dos.writeUTF("TS-PLAYLIST");
         dos.writeInt(0);
         dos.writeInt(data.size());
         
         /*Write playlist items*/
         Iterator<AbstractPlayListItem> items = data.iterator();
         
         while(items.hasNext()) {
             AbstractPlayListItem api = items.next();
             
             String className = api.getClass().getName();
             dos.writeUTF(className);
             api.saveToStream(dos);
         }
         dos.flush();
         dos.close();
     }
     
     public void load(String filespec) throws Exception {
         
         /*Data is going to be replaced*/
         data = new ArrayList();
         
         /* Open output file*/
         FileInputStream fis = new FileInputStream(filespec);
         BufferedInputStream bis = new BufferedInputStream(fis);
         DataInputStream dis = new DataInputStream(bis);
         
         /*Read and check header*/
         String eyeCatcher = dis.readUTF();
         if (!eyeCatcher.equals("TS-PLAYLIST")) throw new FileFormatException("Playlist corrupt. Playlist header not found.");
         
         int version = dis.readInt();
         if (version<0 || version > 0) throw new FileFormatException("Playlist corrupt. Playlist version "+Integer.toString(version)+" not supported.");
         
         int numItems = dis.readInt();
         if (numItems<0) throw new FileFormatException("Playlist corrupt. Negative number of playlist items found in the playlist.");
         
         /*Read the items*/
         for(int i=0;i<numItems;i++) {
             String className = dis.readUTF();
             version = dis.readInt();
             
             AbstractPlayListItem api = (AbstractPlayListItem)(Class.forName(className).newInstance());
             
             if (api!=null) {
                api.loadFromStream(dis, version);
                data.add(api);
             }
         }
         
         /*Notify table*/
         fireTableDataChanged();
         
     }
     
    
     
     
}
