소스 검색

FeaturePlugin handling stage 1 & first iteration of iZplPlugins/GameRadioManager

LH 10 년 전
부모
커밋
daf2e5d49f

+ 33 - 0
iZpl/src/main/java/de/nplusc/izc/iZpl/API/FeaturePlugin.java

@@ -0,0 +1,33 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package de.nplusc.izc.iZpl.API;
+
+/**
+ * FeaturePlugins are to interface to other programs which are not full mediaplayers like games.
+ * @author iZc <nplusc.de>
+ */
+public interface FeaturePlugin extends Plugin
+{
+    /**
+     * Used by the Main method to pass the PluginParameter string to the code
+     * @param param PluginParameter to configure this plugin
+     */
+    public void parseParameter(String param); 
+    
+    
+    /**
+     * Checks whether this plugin got a ConfigureScreen or not
+     * @return true if there is a ConfigureScreen
+     */
+    public boolean hasConfigureScreen();
+    
+    
+    /**
+     * Opens the configureScreen if #hasConfigureScreen() returned true;
+     */
+    public void openConfigureScreen();
+}

+ 132 - 27
iZpl/src/main/java/de/nplusc/izc/iZpl/Main.java

@@ -4,6 +4,7 @@
  */
 package de.nplusc.izc.iZpl;
 
+import de.nplusc.izc.iZpl.API.FeaturePlugin;
 import de.nplusc.izc.iZpl.API.IZPLApi;
 import de.nplusc.izc.iZpl.API.PlaybackPlugin;
 import de.nplusc.izc.iZpl.API.Plugin;
@@ -70,6 +71,7 @@ public class Main extends javax.swing.JFrame
     
     // public static LogStream stdout;
     private static final List<PlaybackPlugin> registeredPlayBackAdapters = new ArrayList<>();
+     private static final List<FeaturePlugin> registeredFeatures = new ArrayList<>();
     private static final List<UIPlugin> registeredUIs = new ArrayList<>();
     private static final List<String> detectedSkins = new ArrayList<>();
     private static boolean loadedVLC = false;
@@ -110,6 +112,11 @@ public class Main extends javax.swing.JFrame
     
     private static Image playListIcon;
     
+    private static boolean featurePluginMode;
+    private static String featurePluginID;
+    private static FeaturePlugin selectedFeaturePlugin;
+    private static String pluginParameter;
+    
     /**
      * Creates new form Builder
      */
@@ -279,6 +286,9 @@ public class Main extends javax.swing.JFrame
         Options options = new Options();
         OptionGroup modes = new OptionGroup();
         OptionGroup uimodes = new OptionGroup();
+        
+        //gopvsferbicux
+        //bcefgioprsuvx
         uimodes.addOption(OptionBuilder.withLongOpt("newgui")
                 .withDescription("enables the Standalone GUI mode. Starts program straight if --file or --resume is set")
                 .create("g"));
@@ -287,6 +297,21 @@ public class Main extends javax.swing.JFrame
                 .create("o"));
         options.addOption("p", "pregen", false, "Pregens a standalone playlist with the randomisation included. Use togehter only with --file");
         options.addOption("v", "verbose", false, "Enables verbose VLCJ logging");
+        
+        
+        options.addOption(OptionBuilder.withLongOpt("pluginparameter")
+                .withDescription("uses the given pluginParameter to initialize the selected FeaturePlugin")
+                .hasOptionalArg()
+                .withArgName("PluginParameter")
+                .create("x"));
+        
+        options.addOption(OptionBuilder.withLongOpt("featureplugin")
+                .withDescription("loads the specified FeaturePlugin. Lists them if no plugin name given")
+                .hasOptionalArg()
+                .withArgName("plugin")
+                .create("e"));
+        
+        
         options.addOption(OptionBuilder.withLongOpt("skin")
                 .withDescription("load FILE as skin. No file specified means default skin")
                 .hasOptionalArg()
@@ -297,6 +322,7 @@ public class Main extends javax.swing.JFrame
                 .hasArg()
                 .withArgName("FILE")
                 .create("f"));
+       
         modes.addOption(OptionBuilder.withLongOpt("resume")
                 .withDescription("load FILE as iZpl-Statefile to resume the playback session")
                 .hasArg()
@@ -354,7 +380,7 @@ public class Main extends javax.swing.JFrame
             quickQuit();
         }
         
-        
+
         
         if (cl.hasOption("resume"))
         {
@@ -366,6 +392,36 @@ public class Main extends javax.swing.JFrame
             statefile = true;
             file_path = cl.getOptionValue("resume");
         }
+        
+        if(cl.hasOption("e"))
+        {
+            if(filemode||statefile)
+            {
+                pluginParameter="";
+                featurePluginMode=true;
+                featurePluginID="";
+                if(cl.getOptionValue("e")!=null)
+                {
+                    featurePluginID=cl.getOptionValue("e");
+                }
+            }
+            else
+            {
+                System.out.println("Error: FeaturePlugins need either a file or a statefile to resume");
+                System.exit(9263);
+            }
+        }
+        
+        if(cl.hasOption("x"))
+        {
+            pluginParameter="";
+            if(cl.getOptionValue("e")!=null)
+            {
+                pluginParameter = cl.getOptionValue("x");
+            }
+        }
+        
+        
         if (cl.hasOption("burn"))
         {
             if (filemode || statefile)
@@ -583,6 +639,7 @@ public class Main extends javax.swing.JFrame
                         boolean isplugin = false;
                         boolean isPlaybackPlugin = false;
                         boolean isUIPlugin = false;
+                        boolean isFeaturePlugin=false;
                         for (int i = 0; i < interfaces.length && !isplugin; i++)
                         {
                             if (interfaces[i].getName().equals("de.nplusc.izc.iZpl.API.PlaybackPlugin"))
@@ -597,6 +654,10 @@ public class Main extends javax.swing.JFrame
                                 isUIPlugin = true;
 
                             }
+                            if(interfaces[i].getName().equals("de.nplusc.izc.iZpl.API.FeaturePlugin"))
+                            {
+                                isplugin=isFeaturePlugin=true;
+                            }
                         }
                         if (isplugin)
                         {
@@ -609,6 +670,10 @@ public class Main extends javax.swing.JFrame
                             {
                                 registeredPlayBackAdapters.add((PlaybackPlugin) pluginInstance);
                             }
+                            if(isFeaturePlugin)
+                            {
+                                registeredFeatures.add((FeaturePlugin)pluginInstance);
+                            }
                         }
                     }
                 }
@@ -623,29 +688,42 @@ public class Main extends javax.swing.JFrame
 
             }
         }
-
-        //PluginHandling stage 2: call the prepareUpgrade handler
-        for (PlaybackPlugin playbackPlugin : registeredPlayBackAdapters)
+        
+        //pluginhandling interception: abort load if only enumerating of Features is wanted
+        if(featurePluginID.equals(""))
         {
-            if (playbackPlugin.getPluginName().equals(CONFIG.getMediaPlayerForStandalone()))
+            System.out.println("Features available:");
+            for (FeaturePlugin featurePlugin : registeredFeatures) 
             {
-                if(firstrunmode||updateInit)
-                    playbackPlugin.prepareUpgrade();
-                selectedPlaybackPlugin = playbackPlugin;
-            }
-        }
-        for (UIPlugin uIPlugin : registeredUIs)
-        {
-            if (uIPlugin.getPluginName().equals(CONFIG.getUsedPluginUI()))
-            {                                                               //incase of a dualPlugin
-                if((firstrunmode||updateInit)&&!(uIPlugin instanceof PlaybackPlugin )&&!registeredPlayBackAdapters.contains(uIPlugin))
-                    uIPlugin.prepareUpgrade();
-                selectedUIPlugin = uIPlugin;
+                System.out.println(featurePlugin.getPluginName());
             }
+            quickQuit();
         }
         
         
         
+        //PluginHandling stage 2: call the prepareUpgrade handler
+        if(firstrunmode||updateInit)
+        {
+            for (PlaybackPlugin playbackPlugin : registeredPlayBackAdapters)
+            {
+                if (playbackPlugin.getPluginName().equals(CONFIG.getMediaPlayerForStandalone()))
+                {
+
+                    playbackPlugin.prepareUpgrade();
+                    selectedPlaybackPlugin = playbackPlugin;
+                }
+            }
+            for (UIPlugin uIPlugin : registeredUIs)
+            {
+                if (uIPlugin.getPluginName().equals(CONFIG.getUsedPluginUI()))
+                {                                                               //incase of a dualPlugin
+                    if(!(uIPlugin instanceof PlaybackPlugin )&&!registeredPlayBackAdapters.contains(uIPlugin))
+                        uIPlugin.prepareUpgrade();
+                    selectedUIPlugin = uIPlugin;
+                }
+            }
+        }
         //PluginHandling stage 3: initialize the plugins
         for (PlaybackPlugin playbackPlugin : registeredPlayBackAdapters)
         {
@@ -665,7 +743,21 @@ public class Main extends javax.swing.JFrame
                 selectedUIPlugin = uIPlugin;
             }
         }
-        if(!firstrunmode&&!updateInit)
+        
+        for (FeaturePlugin featurePlugin : registeredFeatures)
+        {
+            if(featurePlugin.getPluginName().equals(featurePluginID))
+            {
+                selectedFeaturePlugin=featurePlugin;
+                featurePlugin.initializePlugin();
+            }
+        }
+        if(featurePluginMode&&selectedFeaturePlugin==null)
+        {
+            System.out.println("NO valid FeaturePlugin given");
+            quickQuit();
+        }
+        if(!firstrunmode&&!updateInit&&!featurePluginMode)
         {       
             if (selectedPlaybackPlugin != null)
             {
@@ -687,7 +779,7 @@ public class Main extends javax.swing.JFrame
         System.out.println("IZPL-Core:initialized at:" + time);
         String vlcpath = CONFIG.getMPExecutablePath();
         System.err.println("vlcpath=" + vlcpath);
-        if(!useGUI&&vlcpath.equals("")&&!new File(vlcpath).exists())
+        if(!(useGUI||featurePluginMode)&&vlcpath.equals("")&&!new File(vlcpath).exists())
         {
             System.out.println("ungültige MediaPlayer executable");
             quickQuit();
@@ -706,10 +798,12 @@ public class Main extends javax.swing.JFrame
         {
 
             System.out.println("fpl|" + forcePregen + "|shitmp|" + isShittyPlayer + "|a1|" + file_path + "|vp|" + vlcpath);
-            if (filemode && !(forcePregen || isShittyPlayer))
+            if ((filemode && !(forcePregen || isShittyPlayer))||featurePluginMode)
             {
                 System.out.println("usegui=" + useGUI);
-                ps = new PLServer(/*"D:\\mp3\\iZpl\\rxe.izpl"/*/file_path/**/, !useGUI);//DBG_CD3
+                System.out.println("featurePlugin=" + featurePluginMode);
+                
+                ps = new PLServer(/*"D:\\mp3\\iZpl\\rxe.izpl"/*/file_path/**/, !(useGUI||featurePluginMode));//DBG_CD3
                 if (issueDetected)
                 {
                     quickQuit();
@@ -773,14 +867,25 @@ public class Main extends javax.swing.JFrame
                 }
                 else
                 {
-                    boolean crashed = false;
+                    if(featurePluginMode)
+                    {
+                        EventQueue.invokeLater(() ->
+                        {
+                            selectedFeaturePlugin.parseParameter(pluginParameter);
+                        });
                     loadedVLC = true;
-                    do
+                    }
+                    else
                     {
-                        crashed = Tools.runCmdStreamable(null, System.out, false, vlcpath, "--extraintf=cad",/* qt4"--extraintf=http:logger","--verbose=2","--file-logging","--logfile=vlc-log.txt",*/ "http://localhost:9263/rcvr/lst.m3u");//http://localhost:9263/lst.m3u");
-                        System.out.println("VLCExit");
+                        boolean crashed = false;
+                        loadedVLC = true;
+                        do
+                        {
+                            crashed = Tools.runCmdStreamable(null, System.out, false, vlcpath, "--extraintf=cad",/* qt4"--extraintf=http:logger","--verbose=2","--file-logging","--logfile=vlc-log.txt",*/ "http://localhost:9263/rcvr/lst.m3u");//http://localhost:9263/lst.m3u");
+                            System.out.println("VLCExit");
+                        }
+                        while (crashed);
                     }
-                    while (crashed);
                 }
             }
             else
@@ -797,7 +902,7 @@ public class Main extends javax.swing.JFrame
                     }
                 }
             }
-            if (!useGUI)
+            if (!(useGUI||featurePluginMode))
             {
                 checkpointedExit(isShittyPlayer);
             }

+ 1 - 0
iZplPlugins/GameRadio/.gitignore

@@ -0,0 +1 @@
+auxy

+ 12 - 0
iZplPlugins/GameRadio/build.gradle

@@ -0,0 +1,12 @@
+apply plugin:'java'
+task distZip(dependsOn: 'jar') {
+	//NO-OPtask als redirect
+}
+
+dependencies
+{
+	compile fileTree(dir: 'lib', include: '*.jar')
+	compile project(':iZpl')
+}
+
+

+ 264 - 0
iZplPlugins/GameRadio/src/main/java/de/nplusc/izc/izpl/plugins/gameradio/RadioConfig.form

@@ -0,0 +1,264 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
+  <NonVisualComponents>
+    <Component class="javax.swing.ButtonGroup" name="bgrMode">
+    </Component>
+  </NonVisualComponents>
+  <Properties>
+    <Property name="defaultCloseOperation" type="int" value="3"/>
+  </Properties>
+  <SyntheticProperties>
+    <SyntheticProperty name="formSizePolicy" type="int" value="1"/>
+    <SyntheticProperty name="generateCenter" type="boolean" value="false"/>
+  </SyntheticProperties>
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" attributes="0">
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Group type="102" attributes="0">
+                      <Group type="103" groupAlignment="0" attributes="0">
+                          <Group type="102" alignment="0" attributes="0">
+                              <EmptySpace min="-2" pref="34" max="-2" attributes="0"/>
+                              <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
+                          </Group>
+                          <Group type="102" attributes="0">
+                              <EmptySpace min="-2" pref="26" max="-2" attributes="0"/>
+                              <Group type="103" groupAlignment="0" attributes="0">
+                                  <Component id="rbSymlinked" alignment="0" min="-2" max="-2" attributes="0"/>
+                                  <Component id="rbCopyMode" alignment="0" min="-2" max="-2" attributes="0"/>
+                                  <Component id="rbFeedbackMode" alignment="0" min="-2" max="-2" attributes="0"/>
+                              </Group>
+                          </Group>
+                      </Group>
+                      <EmptySpace min="0" pref="0" max="32767" attributes="0"/>
+                  </Group>
+                  <Group type="102" alignment="1" attributes="0">
+                      <EmptySpace min="0" pref="0" max="32767" attributes="0"/>
+                      <Group type="103" groupAlignment="0" max="-2" attributes="0">
+                          <Group type="102" attributes="0">
+                              <Group type="103" groupAlignment="0" attributes="0">
+                                  <Group type="102" alignment="0" attributes="0">
+                                      <EmptySpace min="-2" pref="11" max="-2" attributes="0"/>
+                                      <Component id="jLabel2" min="-2" max="-2" attributes="0"/>
+                                      <EmptySpace min="-2" pref="36" max="-2" attributes="0"/>
+                                      <Group type="103" groupAlignment="0" max="-2" attributes="0">
+                                          <Component id="txfStations" max="32767" attributes="0"/>
+                                          <Component id="txfTracks" min="-2" pref="111" max="-2" attributes="0"/>
+                                      </Group>
+                                  </Group>
+                                  <Component id="jLabel3" alignment="0" min="-2" max="-2" attributes="0"/>
+                              </Group>
+                              <EmptySpace max="-2" attributes="0"/>
+                              <Group type="103" groupAlignment="0" attributes="0">
+                                  <Component id="cbxMerge" min="-2" pref="168" max="-2" attributes="0"/>
+                                  <Component id="cbxFolders" min="-2" max="-2" attributes="0"/>
+                              </Group>
+                          </Group>
+                          <Component id="jLabel4" alignment="0" min="-2" max="-2" attributes="0"/>
+                          <Component id="jScrollPane1" min="-2" pref="333" max="-2" attributes="0"/>
+                          <Group type="102" attributes="0">
+                              <Group type="103" groupAlignment="1" max="-2" attributes="0">
+                                  <Group type="102" attributes="0">
+                                      <Component id="btnRadioize" min="-2" pref="138" max="-2" attributes="0"/>
+                                      <EmptySpace max="-2" attributes="0"/>
+                                      <Component id="btnGetConfig" min="-2" pref="179" max="-2" attributes="0"/>
+                                  </Group>
+                                  <Group type="102" alignment="1" attributes="0">
+                                      <Component id="txfBasePath" max="32767" attributes="0"/>
+                                      <EmptySpace max="-2" attributes="0"/>
+                                      <Component id="jButton1" min="-2" pref="119" max="-2" attributes="0"/>
+                                  </Group>
+                              </Group>
+                              <EmptySpace pref="54" max="32767" attributes="0"/>
+                          </Group>
+                      </Group>
+                  </Group>
+                  <Group type="102" alignment="1" attributes="0">
+                      <EmptySpace min="0" pref="15" max="32767" attributes="0"/>
+                      <Component id="jLabel5" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace pref="19" max="32767" attributes="0"/>
+                      <Component id="txfStationNameBase" min="-2" pref="198" max="-2" attributes="0"/>
+                      <EmptySpace min="-2" pref="79" max="-2" attributes="0"/>
+                  </Group>
+              </Group>
+              <EmptySpace max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace min="-2" pref="5" max="-2" attributes="0"/>
+              <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+              <Component id="rbSymlinked" min="-2" max="-2" attributes="0"/>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+              <Component id="rbCopyMode" min="-2" max="-2" attributes="0"/>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+              <Component id="rbFeedbackMode" min="-2" max="-2" attributes="0"/>
+              <EmptySpace type="separate" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="3" attributes="0">
+                  <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="txfStations" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="cbxFolders" alignment="3" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace type="separate" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="3" attributes="0">
+                  <Component id="txfTracks" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="cbxMerge" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="3" attributes="0">
+                  <Component id="txfStationNameBase" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="jLabel5" alignment="3" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace min="-2" pref="12" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="3" attributes="0">
+                  <Component id="txfBasePath" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="jButton1" alignment="3" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="1" attributes="0">
+                  <Component id="btnRadioize" min="-2" pref="47" max="-2" attributes="0"/>
+                  <Component id="btnGetConfig" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace type="separate" max="-2" attributes="0"/>
+              <Component id="jLabel4" min="-2" max="-2" attributes="0"/>
+              <EmptySpace min="-2" pref="3" max="-2" attributes="0"/>
+              <Component id="jScrollPane1" min="-2" pref="74" max="-2" attributes="0"/>
+              <EmptySpace max="32767" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Component class="javax.swing.JRadioButton" name="rbSymlinked">
+      <Properties>
+        <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
+          <ComponentRef name="bgrMode"/>
+        </Property>
+        <Property name="text" type="java.lang.String" value="Symlinked Mode"/>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="rbSymlinkedActionPerformed"/>
+      </Events>
+    </Component>
+    <Component class="javax.swing.JRadioButton" name="rbCopyMode">
+      <Properties>
+        <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
+          <ComponentRef name="bgrMode"/>
+        </Property>
+        <Property name="text" type="java.lang.String" value="Copy Mode"/>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="rbCopyModeActionPerformed"/>
+      </Events>
+    </Component>
+    <Component class="javax.swing.JRadioButton" name="rbFeedbackMode">
+      <Properties>
+        <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
+          <ComponentRef name="bgrMode"/>
+        </Property>
+        <Property name="text" type="java.lang.String" value="Feedback Mode"/>
+        <Property name="enabled" type="boolean" value="false"/>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="jLabel1">
+      <Properties>
+        <Property name="text" type="java.lang.String" value="Mode"/>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JTextField" name="txfTracks">
+    </Component>
+    <Component class="javax.swing.JCheckBox" name="cbxMerge">
+      <Properties>
+        <Property name="text" type="java.lang.String" value="Merge Tracks"/>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="jLabel2">
+      <Properties>
+        <Property name="text" type="java.lang.String" value="Tracks"/>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="jLabel3">
+      <Properties>
+        <Property name="text" type="java.lang.String" value="Stations"/>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JTextField" name="txfStations">
+    </Component>
+    <Component class="javax.swing.JCheckBox" name="cbxFolders">
+      <Properties>
+        <Property name="text" type="java.lang.String" value="Folders for stations?"/>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cbxFoldersActionPerformed"/>
+      </Events>
+    </Component>
+    <Component class="javax.swing.JButton" name="btnRadioize">
+      <Properties>
+        <Property name="text" type="java.lang.String" value="Radio-ize!"/>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnRadioizeActionPerformed"/>
+      </Events>
+    </Component>
+    <Container class="javax.swing.JScrollPane" name="jScrollPane1">
+      <AuxValues>
+        <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
+      </AuxValues>
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+      <SubComponents>
+        <Component class="javax.swing.JTextArea" name="txaCString">
+          <Properties>
+            <Property name="columns" type="int" value="20"/>
+            <Property name="rows" type="int" value="5"/>
+          </Properties>
+        </Component>
+      </SubComponents>
+    </Container>
+    <Component class="javax.swing.JLabel" name="jLabel4">
+      <Properties>
+        <Property name="text" type="java.lang.String" value="Config-String:"/>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JButton" name="btnGetConfig">
+      <Properties>
+        <Property name="text" type="java.lang.String" value="get Configstring"/>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnGetConfigActionPerformed"/>
+      </Events>
+    </Component>
+    <Component class="javax.swing.JButton" name="jButton1">
+      <Properties>
+        <Property name="text" type="java.lang.String" value="BasePath select"/>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JTextField" name="txfBasePath">
+    </Component>
+    <Component class="javax.swing.JTextField" name="txfStationNameBase">
+    </Component>
+    <Component class="javax.swing.JLabel" name="jLabel5">
+      <Properties>
+        <Property name="text" type="java.lang.String" value="Station baseName"/>
+      </Properties>
+    </Component>
+  </SubComponents>
+</Form>

+ 441 - 0
iZplPlugins/GameRadio/src/main/java/de/nplusc/izc/izpl/plugins/gameradio/RadioConfig.java

@@ -0,0 +1,441 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package de.nplusc.izc.izpl.plugins.gameradio;
+
+import de.nplusc.izc.tools.baseTools.Messagers;
+import java.io.File;
+import java.io.IOException;
+import javax.swing.JOptionPane;
+
+/**
+ *
+ * @author iZc <nplusc.de>
+ */
+public class RadioConfig extends javax.swing.JFrame
+{
+    RadioManager mgr;
+    /**
+     * Creates new form RadioConfig
+     * @param r Reference for the radioManager that opened this UI
+     */
+    public RadioConfig(RadioManager r)
+    {
+        mgr=r;
+        initComponents();
+        
+    }
+
+    /**
+     * This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents()
+    {
+
+        bgrMode = new javax.swing.ButtonGroup();
+        rbSymlinked = new javax.swing.JRadioButton();
+        rbCopyMode = new javax.swing.JRadioButton();
+        rbFeedbackMode = new javax.swing.JRadioButton();
+        jLabel1 = new javax.swing.JLabel();
+        txfTracks = new javax.swing.JTextField();
+        cbxMerge = new javax.swing.JCheckBox();
+        jLabel2 = new javax.swing.JLabel();
+        jLabel3 = new javax.swing.JLabel();
+        txfStations = new javax.swing.JTextField();
+        cbxFolders = new javax.swing.JCheckBox();
+        btnRadioize = new javax.swing.JButton();
+        jScrollPane1 = new javax.swing.JScrollPane();
+        txaCString = new javax.swing.JTextArea();
+        jLabel4 = new javax.swing.JLabel();
+        btnGetConfig = new javax.swing.JButton();
+        jButton1 = new javax.swing.JButton();
+        txfBasePath = new javax.swing.JTextField();
+        txfStationNameBase = new javax.swing.JTextField();
+        jLabel5 = new javax.swing.JLabel();
+
+        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+
+        bgrMode.add(rbSymlinked);
+        rbSymlinked.setText("Symlinked Mode");
+        rbSymlinked.addActionListener(new java.awt.event.ActionListener()
+        {
+            public void actionPerformed(java.awt.event.ActionEvent evt)
+            {
+                rbSymlinkedActionPerformed(evt);
+            }
+        });
+
+        bgrMode.add(rbCopyMode);
+        rbCopyMode.setText("Copy Mode");
+        rbCopyMode.addActionListener(new java.awt.event.ActionListener()
+        {
+            public void actionPerformed(java.awt.event.ActionEvent evt)
+            {
+                rbCopyModeActionPerformed(evt);
+            }
+        });
+
+        bgrMode.add(rbFeedbackMode);
+        rbFeedbackMode.setText("Feedback Mode");
+        rbFeedbackMode.setEnabled(false);
+
+        jLabel1.setText("Mode");
+
+        cbxMerge.setText("Merge Tracks");
+
+        jLabel2.setText("Tracks");
+
+        jLabel3.setText("Stations");
+
+        cbxFolders.setText("Folders for stations?");
+        cbxFolders.addActionListener(new java.awt.event.ActionListener()
+        {
+            public void actionPerformed(java.awt.event.ActionEvent evt)
+            {
+                cbxFoldersActionPerformed(evt);
+            }
+        });
+
+        btnRadioize.setText("Radio-ize!");
+        btnRadioize.addActionListener(new java.awt.event.ActionListener()
+        {
+            public void actionPerformed(java.awt.event.ActionEvent evt)
+            {
+                btnRadioizeActionPerformed(evt);
+            }
+        });
+
+        txaCString.setColumns(20);
+        txaCString.setRows(5);
+        jScrollPane1.setViewportView(txaCString);
+
+        jLabel4.setText("Config-String:");
+
+        btnGetConfig.setText("get Configstring");
+        btnGetConfig.addActionListener(new java.awt.event.ActionListener()
+        {
+            public void actionPerformed(java.awt.event.ActionEvent evt)
+            {
+                btnGetConfigActionPerformed(evt);
+            }
+        });
+
+        jButton1.setText("BasePath select");
+
+        jLabel5.setText("Station baseName");
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+        getContentPane().setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(layout.createSequentialGroup()
+                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                            .addGroup(layout.createSequentialGroup()
+                                .addGap(34, 34, 34)
+                                .addComponent(jLabel1))
+                            .addGroup(layout.createSequentialGroup()
+                                .addGap(26, 26, 26)
+                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                                    .addComponent(rbSymlinked)
+                                    .addComponent(rbCopyMode)
+                                    .addComponent(rbFeedbackMode))))
+                        .addGap(0, 0, Short.MAX_VALUE))
+                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+                        .addGap(0, 0, Short.MAX_VALUE)
+                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+                            .addGroup(layout.createSequentialGroup()
+                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                                    .addGroup(layout.createSequentialGroup()
+                                        .addGap(11, 11, 11)
+                                        .addComponent(jLabel2)
+                                        .addGap(36, 36, 36)
+                                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+                                            .addComponent(txfStations)
+                                            .addComponent(txfTracks, javax.swing.GroupLayout.PREFERRED_SIZE, 111, javax.swing.GroupLayout.PREFERRED_SIZE)))
+                                    .addComponent(jLabel3))
+                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                                    .addComponent(cbxMerge, javax.swing.GroupLayout.PREFERRED_SIZE, 168, javax.swing.GroupLayout.PREFERRED_SIZE)
+                                    .addComponent(cbxFolders)))
+                            .addComponent(jLabel4)
+                            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 333, javax.swing.GroupLayout.PREFERRED_SIZE)
+                            .addGroup(layout.createSequentialGroup()
+                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
+                                    .addGroup(layout.createSequentialGroup()
+                                        .addComponent(btnRadioize, javax.swing.GroupLayout.PREFERRED_SIZE, 138, javax.swing.GroupLayout.PREFERRED_SIZE)
+                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                                        .addComponent(btnGetConfig, javax.swing.GroupLayout.PREFERRED_SIZE, 179, javax.swing.GroupLayout.PREFERRED_SIZE))
+                                    .addGroup(layout.createSequentialGroup()
+                                        .addComponent(txfBasePath)
+                                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                                        .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 119, javax.swing.GroupLayout.PREFERRED_SIZE)))
+                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 54, Short.MAX_VALUE))))
+                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+                        .addGap(0, 15, Short.MAX_VALUE)
+                        .addComponent(jLabel5)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 19, Short.MAX_VALUE)
+                        .addComponent(txfStationNameBase, javax.swing.GroupLayout.PREFERRED_SIZE, 198, javax.swing.GroupLayout.PREFERRED_SIZE)
+                        .addGap(79, 79, 79)))
+                .addContainerGap())
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addGap(5, 5, 5)
+                .addComponent(jLabel1)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addComponent(rbSymlinked)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addComponent(rbCopyMode)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addComponent(rbFeedbackMode)
+                .addGap(18, 18, 18)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(jLabel3)
+                    .addComponent(txfStations, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                    .addComponent(cbxFolders))
+                .addGap(18, 18, 18)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(txfTracks, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                    .addComponent(cbxMerge)
+                    .addComponent(jLabel2))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(txfStationNameBase, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                    .addComponent(jLabel5))
+                .addGap(12, 12, 12)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(txfBasePath, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                    .addComponent(jButton1))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+                    .addComponent(btnRadioize, javax.swing.GroupLayout.PREFERRED_SIZE, 47, javax.swing.GroupLayout.PREFERRED_SIZE)
+                    .addComponent(btnGetConfig))
+                .addGap(18, 18, 18)
+                .addComponent(jLabel4)
+                .addGap(3, 3, 3)
+                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 74, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+        );
+
+        pack();
+    }// </editor-fold>//GEN-END:initComponents
+
+    private boolean previousSelectionState=false;
+    
+    private void cbxFoldersActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cbxFoldersActionPerformed
+    {//GEN-HEADEREND:event_cbxFoldersActionPerformed
+       if(cbxMerge.isEnabled())
+       {
+           previousSelectionState=cbxMerge.isSelected();
+           cbxMerge.setSelected(true);
+           
+       }
+       else
+       {
+           cbxMerge.setSelected(previousSelectionState);
+       }
+       cbxMerge.setEnabled(!cbxFolders.isSelected());
+    }//GEN-LAST:event_cbxFoldersActionPerformed
+
+    
+    
+    private void updateRadioButtonState()
+    {
+        if(rbSymlinked.isSelected())
+        {
+            if(cbxMerge.isSelected())
+            {
+                JOptionPane.showMessageDialog(this, "Cannot use symlink-mode with merged files", "Input error", JOptionPane.ERROR_MESSAGE);
+                rbCopyMode.setSelected(true);
+            }
+            else
+            {
+                if(cbxFolders.isSelected())
+                {
+                    JOptionPane.showMessageDialog(this, "1 track/station doesnt make sense without merging", "Input error", JOptionPane.ERROR_MESSAGE);
+                  rbCopyMode.setSelected(true);
+                }
+                else
+                {
+                    cbxFolders.setEnabled(false);
+                    cbxMerge.setEnabled(false);
+                }
+            }
+        }
+        else
+        {
+            cbxFolders.setEnabled(true);
+            cbxMerge.setEnabled(true);
+        }
+    }
+    
+    
+    private void rbSymlinkedActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_rbSymlinkedActionPerformed
+    {//GEN-HEADEREND:event_rbSymlinkedActionPerformed
+        updateRadioButtonState();
+    }//GEN-LAST:event_rbSymlinkedActionPerformed
+
+    private void rbCopyModeActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_rbCopyModeActionPerformed
+    {//GEN-HEADEREND:event_rbCopyModeActionPerformed
+       updateRadioButtonState();
+    }//GEN-LAST:event_rbCopyModeActionPerformed
+
+    private void btnRadioizeActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnRadioizeActionPerformed
+    {//GEN-HEADEREND:event_btnRadioizeActionPerformed
+        processData(true);
+        
+    }//GEN-LAST:event_btnRadioizeActionPerformed
+
+    private void btnGetConfigActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnGetConfigActionPerformed
+    {//GEN-HEADEREND:event_btnGetConfigActionPerformed
+        processData(false);
+    }//GEN-LAST:event_btnGetConfigActionPerformed
+
+    
+    private void processData(boolean radioize)
+    {
+        int tracks=-1;
+        int stations=1;
+        try{
+            tracks=Integer.valueOf(txfTracks.getText());
+            stations=Integer.valueOf(txfStations.getText());
+        }
+        catch(NumberFormatException x)
+        {
+            JOptionPane.showMessageDialog(this, "Letters are no numbers!!!", "Input error", JOptionPane.ERROR_MESSAGE);
+            return;      
+        }
+        if(stations>65535)
+        {
+            JOptionPane.showMessageDialog(this, "Folders dont support more than 65535 direct subfolders/files", "Input error", JOptionPane.ERROR_MESSAGE);
+            return;    
+        }
+        if(tracks>65535&&!cbxMerge.isSelected())
+        {
+            JOptionPane.showMessageDialog(this, "Folders dont support more than 65535 direct subfolders/files", "Input error", JOptionPane.ERROR_MESSAGE);
+            return;  
+        }
+        if(!(new File(txfBasePath.getText()).exists()))
+        {
+            JOptionPane.showMessageDialog(this, "Basepath must be there!!", "Input error", JOptionPane.ERROR_MESSAGE);
+            return;  
+        }
+        
+        try
+        {
+            if(!(new File(txfBasePath.getText()+File.separator+txfStationNameBase.getText()).getCanonicalPath()!=null))
+            {  
+                JOptionPane.showMessageDialog(this, "BaseName for the stations must be a valid filename", "Input error", JOptionPane.ERROR_MESSAGE);
+                return;
+            }
+        }
+        catch (IOException ex)
+        {
+           JOptionPane.showMessageDialog(this, "BaseName for the stations must be a valid filename", "Input error", JOptionPane.ERROR_MESSAGE);
+                return;
+        }
+        
+        //Scheme of cmdstring:
+        //B means T or F as boolean value
+        //I means Integer
+        //S=String
+        //P=Pfad, muss am ende stehen
+        //header:rbSym:rbCopy:rbInter:Stations:Stationsasfile:Tracks:cxMergeTracks:StationBaseName:RadioPath
+        //radio:B:B:B:I:B:I:B:S:P
+        
+        String commandString = "radio:"+(rbSymlinked.isSelected()?"T":"F")+":"+(rbCopyMode.isSelected()?"T":"F")+
+                ":"+(rbFeedbackMode.isSelected()?"T":"F")+":"+stations+":"+(cbxFolders.isSelected()?"T":"F")+":"+tracks+":"+
+                (cbxMerge.isSelected()?"T":"F")+":"+txfStationNameBase.getText()+":"+txfBasePath.getText();
+        
+        txaCString.setText(commandString);
+        
+        if(radioize)
+        {
+            mgr.parseParameter(commandString);
+        }
+    }
+    
+    
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String args[])
+    {
+        /* Set the Nimbus look and feel */
+        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
+        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
+         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
+         */
+        try
+        {
+            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels())
+            {
+                if ("Nimbus".equals(info.getName()))
+                {
+                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
+                    break;
+                }
+            }
+        }
+        catch (ClassNotFoundException ex)
+        {
+            java.util.logging.Logger.getLogger(RadioConfig.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
+        }
+        catch (InstantiationException ex)
+        {
+            java.util.logging.Logger.getLogger(RadioConfig.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
+        }
+        catch (IllegalAccessException ex)
+        {
+            java.util.logging.Logger.getLogger(RadioConfig.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
+        }
+        catch (javax.swing.UnsupportedLookAndFeelException ex)
+        {
+            java.util.logging.Logger.getLogger(RadioConfig.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
+        }
+        //</editor-fold>
+
+        /* Create and display the form */
+        java.awt.EventQueue.invokeLater(new Runnable()
+        {
+            public void run()
+            {
+                new RadioConfig(new RadioManager()).setVisible(true);
+            }
+        });
+    }
+
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.ButtonGroup bgrMode;
+    private javax.swing.JButton btnGetConfig;
+    private javax.swing.JButton btnRadioize;
+    private javax.swing.JCheckBox cbxFolders;
+    private javax.swing.JCheckBox cbxMerge;
+    private javax.swing.JButton jButton1;
+    private javax.swing.JLabel jLabel1;
+    private javax.swing.JLabel jLabel2;
+    private javax.swing.JLabel jLabel3;
+    private javax.swing.JLabel jLabel4;
+    private javax.swing.JLabel jLabel5;
+    private javax.swing.JScrollPane jScrollPane1;
+    private javax.swing.JRadioButton rbCopyMode;
+    private javax.swing.JRadioButton rbFeedbackMode;
+    private javax.swing.JRadioButton rbSymlinked;
+    private javax.swing.JTextArea txaCString;
+    private javax.swing.JTextField txfBasePath;
+    private javax.swing.JTextField txfStationNameBase;
+    private javax.swing.JTextField txfStations;
+    private javax.swing.JTextField txfTracks;
+    // End of variables declaration//GEN-END:variables
+}

+ 197 - 0
iZplPlugins/GameRadio/src/main/java/de/nplusc/izc/izpl/plugins/gameradio/RadioManager.java

@@ -0,0 +1,197 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package de.nplusc.izc.izpl.plugins.gameradio;
+
+import com.sun.glass.ui.Cursor;
+import de.nplusc.izc.iZpl.API.FeaturePlugin;
+import de.nplusc.izc.iZpl.API.IZPLApi;
+import de.nplusc.izc.iZpl.API.MultiPlayListItem;
+import de.nplusc.izc.iZpl.API.PlayListItem;
+import de.nplusc.izc.iZpl.API.SinglePlayListItem;
+import de.nplusc.izc.tools.IOtools.FileTK;
+import java.io.File;
+import java.util.Arrays;
+
+/**
+ *
+ * @author iZc <nplusc.de>
+ */
+public class RadioManager implements FeaturePlugin
+{
+
+    //header:rbSym:rbCopy:rbInter:Stations:Stationsasfile:Tracks:cxMergeTracks:StationBaseName:RadioPath
+        //radio:B:B:B:I:B:I:B:S:P
+    
+    private enum Mode{
+        SYMLINKED,COPY,INTERACTIVE;
+    }
+    
+    @Override
+    public void parseParameter(String param)
+    {
+        if(!(param.equals(""))&&param.startsWith("radio:"))
+        {
+            String[] cstring = param.split(":");
+            if(cstring.length<10)//patsh can cause that more than 10 :s appear, that error is handled later
+            {
+                System.err.println("DERP the string was invalid");
+                System.err.println("Not enough Sections");
+            }
+            System.out.println(Arrays.toString(cstring));
+            Mode m=null;
+            String mode=param.substring(6,11);
+            switch(mode)
+            {
+                case "T:F:F":
+                    m=Mode.SYMLINKED;
+                    break;
+                case "F:T:F":
+                    m=Mode.COPY;
+                    break;
+                case "F:F:T":
+                    m=Mode.INTERACTIVE;
+                    break;
+                default:
+                    System.err.println("DERP the string was invalid");
+                    System.err.println("Invalid Mode block");
+                    IZPLApi.quickQuitWithoutSaving();
+            }
+            int stations=0;
+            int tracks=0;
+            try
+            {
+                System.err.println(cstring[4]);
+                System.err.println(cstring[6]);
+                stations=Integer.valueOf(cstring[4]);
+                tracks=Integer.valueOf(cstring[6]);
+            }
+            catch(NumberFormatException x)
+            {
+                System.err.println("DERP the string was invalid");
+                System.err.println("Numeric Literals are wrong");
+                IZPLApi.quickQuitWithoutSaving();
+            }
+            boolean fileStations=cstring[5].equals("T");
+            boolean mergeTracks=cstring[7].equals("T");
+            
+            String stationBase = cstring[8];
+            
+            String baseDir = param.substring((cstring[0]+":"+cstring[1]+":"+cstring[2]+":"+cstring[3]+
+                    cstring[4]+":"+cstring[5]+":"+cstring[6]+":"+cstring[7]+":"+cstring[8]+":").length()+1);
+            System.out.println(baseDir);
+            if(!(new File(baseDir).exists()))
+            {
+                
+                System.err.println("DERP the string was invalid");
+                System.err.println("Basedir must be valid");
+                IZPLApi.quickQuitWithoutSaving();
+            }
+            //end simple checks
+            //validate inter-selection stuff
+            
+            if(fileStations&&!mergeTracks)
+            {
+                System.err.println("DERP the string was invalid");
+                System.err.println("fileStations requires merged Tracks");
+                IZPLApi.quickQuitWithoutSaving();
+            }
+            
+            if(m==Mode.SYMLINKED&&mergeTracks)
+            {
+                System.err.println("DERP the string was invalid");
+                System.err.println("YOu cannot symlink and merge tracks at once");
+                IZPLApi.quickQuitWithoutSaving();
+            }
+            
+            if(stations>65535)
+            {
+                System.err.println("DERP the string was invalid");
+                System.err.println("Stations can be at 65535 maximum due to Filesystem constraints");
+                IZPLApi.quickQuitWithoutSaving();
+            }
+            if((tracks>65535&&!mergeTracks))
+            {
+                System.err.println("DERP the string was invalid");
+                System.err.println("more than 65535 tracks require merged Tracks");
+                IZPLApi.quickQuitWithoutSaving();
+            }
+            
+            System.out.println("Selected Settings:\n"
+                    + "Mode: "+m+"\n"
+                    + "Amount of tracks: "+tracks+"\n"
+                    + "Tracks merged: "+mergeTracks+"\n"
+                    + "Amount of stations: "+stations+"\n"
+                    + "Stations as file: "+fileStations+"\n"
+                    + "Station name base: "+stationBase+"\n"
+                    + "Base directory: "+baseDir);
+            if(m==Mode.COPY)
+            {
+                if(!mergeTracks)
+                {
+                    for(int i=0;i<stations;i++)
+                    {
+                        for(int j=0;j<tracks;j++)
+                        {
+                            String pli = getPlayListItemPath();
+                            FileTK.kopierpaste(new File(pli), new File(baseDir+File.separator+stationBase+"_"+i+File.separator+FileTK.getFileName(pli)));
+                        }
+                    }
+                }
+                else
+                {
+                    throw new UnsupportedOperationException("Dont do that!");
+                }
+            }
+        }
+        else
+        {
+            openConfigureScreen();
+        }
+    }
+
+    @Override
+    public boolean hasConfigureScreen()
+    {
+        return true;
+    }
+
+    @Override
+    public void openConfigureScreen()
+    {
+        new RadioConfig(this).setVisible(true);
+    }
+
+    @Override
+    public String getPluginName()
+    {
+        return "GameRadioManager";
+    }
+
+    @Override
+    public void initializePlugin()
+    {
+        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    }
+
+    @Override
+    public void prepareUpgrade()
+    {
+        //NO-OP
+    }
+    
+    private String getPlayListItemPath()
+    {
+        PlayListItem itm = IZPLApi.getNextItem();
+        while (!(itm instanceof SinglePlayListItem))
+        {
+            itm = IZPLApi.getNextItem();
+        }
+        return ((SinglePlayListItem) itm).getPath();
+    }
+            
+    
+}

+ 8 - 0
iZplPlugins/GameRadio/src/main/resources/plugin.yml

@@ -0,0 +1,8 @@
+pluginbaseclass: de.nplusc.izc.izpl.pluginsgameradio.radioManager
+supportedoses:
+  - 'windows'
+# can be windows, mac or linux
+supportedarchitectures:
+  - 'x86'
+  - 'x64'
+# x86 or x64 valid

+ 1 - 1
settings.gradle

@@ -1,2 +1,2 @@
 include 'ToolKit','iZpl',  'izsetup','WPCMgr','UpidTK', 'izstreamer', 'LogBlockHeatMapper','DefaultUIFile','iZlaunch',
-'iZpaqSFX','MazeViewer','TWPUtil',"iZplPlugins:WMP","iZplPlugins:foobar2000_others","iZplPlugins:itunes"
+'iZpaqSFX','MazeViewer','TWPUtil',"iZplPlugins:WMP","iZplPlugins:foobar2000_others","iZplPlugins:itunes","iZplPlugins:gameradio"