diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..3c96d64
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/.project b/.project
new file mode 100644
index 0000000..65ce72c
--- /dev/null
+++ b/.project
@@ -0,0 +1,23 @@
+
+
+ Dionysus
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..6a825c7
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,13 @@
+
+ 4.0.0
+ net.persei.dionysus
+ Dionysus
+ 0.0.1-SNAPSHOT
+
+
+ uk.co.caprica
+ vlcj
+ 3.8.0
+
+
+
\ No newline at end of file
diff --git a/src/main/java/net/persei/dionysus/AudioPlayer.java b/src/main/java/net/persei/dionysus/AudioPlayer.java
new file mode 100644
index 0000000..a389ba2
--- /dev/null
+++ b/src/main/java/net/persei/dionysus/AudioPlayer.java
@@ -0,0 +1,45 @@
+package net.persei.dionysus;
+
+import uk.co.caprica.vlcj.component.AudioMediaPlayerComponent;
+import uk.co.caprica.vlcj.player.MediaPlayer;
+
+public class AudioPlayer implements Player {
+
+ private AudioMediaPlayerComponent player;
+ private boolean loop = false;
+ private String name;
+
+ public AudioPlayer(String name) {
+ this.name = name;
+ player = new AudioMediaPlayerComponent();
+ }
+
+ public boolean isLoop() {
+ return loop;
+ }
+
+ public void playFile(String file) {
+ getMediaPlayer().playMedia(file);
+ }
+
+ public void play() {
+ getMediaPlayer().play();
+ }
+
+ public void pause() {
+ getMediaPlayer().pause();
+ }
+
+ public void setLoop(boolean loop) {
+ this.loop = loop;
+ getMediaPlayer().setRepeat(loop);
+ }
+
+ public MediaPlayer getMediaPlayer() {
+ return player.getMediaPlayer();
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/src/main/java/net/persei/dionysus/Main.java b/src/main/java/net/persei/dionysus/Main.java
new file mode 100644
index 0000000..5842d8b
--- /dev/null
+++ b/src/main/java/net/persei/dionysus/Main.java
@@ -0,0 +1,27 @@
+package net.persei.dionysus;
+
+import net.persei.dionysus.exceptions.LibrariesNotFoundException;
+import uk.co.caprica.vlcj.binding.LibVlc;
+import uk.co.caprica.vlcj.discovery.NativeDiscovery;
+
+public class Main {
+
+ public static final String TITLE = "Dionysus";
+ private static PlayerGUI playerGUI;
+
+ /**
+ * @param args
+ * @throws LibrariesNotFoundException
+ */
+ public static void main(String[] args) throws LibrariesNotFoundException {
+ if (!findLibs())
+ throw new LibrariesNotFoundException();
+
+ System.out.println(LibVlc.INSTANCE.libvlc_get_version());
+ }
+
+ private static boolean findLibs() {
+ return new NativeDiscovery().discover();
+ }
+
+}
diff --git a/src/main/java/net/persei/dionysus/MidiTrigger.java b/src/main/java/net/persei/dionysus/MidiTrigger.java
new file mode 100644
index 0000000..40f68da
--- /dev/null
+++ b/src/main/java/net/persei/dionysus/MidiTrigger.java
@@ -0,0 +1,5 @@
+package net.persei.dionysus;
+
+public class MidiTrigger {
+
+}
diff --git a/src/main/java/net/persei/dionysus/Player.java b/src/main/java/net/persei/dionysus/Player.java
new file mode 100644
index 0000000..7100668
--- /dev/null
+++ b/src/main/java/net/persei/dionysus/Player.java
@@ -0,0 +1,13 @@
+package net.persei.dionysus;
+
+import uk.co.caprica.vlcj.player.MediaPlayer;
+
+public interface Player {
+ boolean isLoop();
+ void playFile(String file);
+ void play();
+ void pause();
+ void setLoop(boolean loop);
+ MediaPlayer getMediaPlayer();
+ String getName();
+}
diff --git a/src/main/java/net/persei/dionysus/PlayerGUI.java b/src/main/java/net/persei/dionysus/PlayerGUI.java
new file mode 100644
index 0000000..f7dee8f
--- /dev/null
+++ b/src/main/java/net/persei/dionysus/PlayerGUI.java
@@ -0,0 +1,79 @@
+package net.persei.dionysus;
+
+import java.awt.HeadlessException;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+import javax.swing.JFrame;
+
+import uk.co.caprica.vlcj.component.EmbeddedMediaPlayerComponent;
+import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;
+
+public class PlayerGUI extends JFrame implements Player {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6068058949441154348L;
+
+ private EmbeddedMediaPlayerComponent player = new EmbeddedMediaPlayerComponent();
+
+ private boolean loop = false;
+ private boolean fullscreen = false;
+
+ public boolean isFullscreen() {
+ return fullscreen;
+ }
+
+ public PlayerGUI(boolean fullscreen) throws HeadlessException {
+ this();
+ dispose();
+ if (fullscreen) {
+ setExtendedState(JFrame.MAXIMIZED_BOTH);
+ setUndecorated(true);
+ }
+ setVisible(true);
+ }
+ public PlayerGUI() throws HeadlessException {
+ super(Main.TITLE);
+ setBounds(100, 100, 600, 400);
+ setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+ setVisible(true);
+
+ setContentPane(player);
+
+ addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowClosing(WindowEvent e) {
+ player.release();
+ System.out.println("release");
+ System.exit(0);
+ }
+ });
+ }
+
+ public boolean isLoop() {
+ return loop;
+ }
+
+ public void setLoop(boolean loop) {
+ this.loop = loop;
+ getMediaPlayer().setRepeat(loop);
+ }
+
+ public void playFile(String file) {
+ getMediaPlayer().playMedia(file);
+ }
+
+ public void play() {
+ getMediaPlayer().play();
+ }
+
+ public void pause() {
+ getMediaPlayer().pause();
+ }
+
+ public EmbeddedMediaPlayer getMediaPlayer() {
+ return player.getMediaPlayer();
+ }
+}
diff --git a/src/main/java/net/persei/dionysus/Setup.java b/src/main/java/net/persei/dionysus/Setup.java
new file mode 100644
index 0000000..2712b3f
--- /dev/null
+++ b/src/main/java/net/persei/dionysus/Setup.java
@@ -0,0 +1,37 @@
+package net.persei.dionysus;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import net.persei.dionysus.blocks.InitialBlock;
+
+public class Setup {
+ private List initBlocks = new LinkedList();
+ private List players = new LinkedList();
+
+ // ugly, but necessary for flexible states
+ private List states = new LinkedList(){{
+ push("none");
+ }};
+ private int state = 0;
+
+ public List getInitBlocks() {
+ return initBlocks;
+ }
+
+ public List getPlayers() {
+ return players;
+ }
+
+ public String getState() {
+ return states.get(state);
+ }
+
+ public void setState(int state) {
+ this.state = state;
+ }
+
+ public List getStates() {
+ return states;
+ }
+}
diff --git a/src/main/java/net/persei/dionysus/blocks/Block.java b/src/main/java/net/persei/dionysus/blocks/Block.java
new file mode 100644
index 0000000..9565f33
--- /dev/null
+++ b/src/main/java/net/persei/dionysus/blocks/Block.java
@@ -0,0 +1,29 @@
+package net.persei.dionysus.blocks;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import net.persei.dionysus.exceptions.UnexpectedDataTypeException;
+
+public abstract class Block {
+ protected String name;
+ protected BlockType type;
+ protected List lanes = new LinkedList();
+
+ public List getOutputLanes() {
+ return lanes;
+ }
+ public String getName() {
+ return name;
+ }
+ public BlockType getType() {
+ return type;
+ }
+
+ public boolean preMagic (Data input, Lane lane) throws Exception {
+ BlockHelper.addPassLog(input, "blocks", this);
+ return magic(input, lane);
+ }
+
+ abstract public boolean magic(Data input, Lane lane) throws Exception;
+}
diff --git a/src/main/java/net/persei/dionysus/blocks/BlockCondition.java b/src/main/java/net/persei/dionysus/blocks/BlockCondition.java
new file mode 100644
index 0000000..d5731bf
--- /dev/null
+++ b/src/main/java/net/persei/dionysus/blocks/BlockCondition.java
@@ -0,0 +1,111 @@
+package net.persei.dionysus.blocks;
+
+import java.util.Map;
+
+import net.persei.dionysus.Setup;
+import net.persei.dionysus.exceptions.DataValueNotAvailableException;
+import net.persei.dionysus.exceptions.MalformedBlockConditionException;
+
+public class BlockCondition {
+
+ private String condition;
+
+ public BlockCondition(String condition) {
+ condition = condition.replace(" ", "");
+ condition = condition.replace(" ", "");
+ condition = condition.replace("\n", "");
+ condition = condition.replace("\r", "");
+
+ this.condition = condition;
+ }
+
+ public boolean parse(Data input) throws MalformedBlockConditionException, DataValueNotAvailableException {
+ String tmp = new String(condition);
+
+ while(true) {
+ if (tmp.indexOf("(") < 0)
+ break;
+
+ int open = 0;
+ while(tmp.indexOf("(", open + 1) >= 0) {
+ open = tmp.indexOf("(", open + 1);
+ }
+ int close = tmp.indexOf(")", open);
+
+ if (close == -1)
+ throw new MalformedBlockConditionException();
+
+ String sub = tmp.substring(open + 1, close - 1);
+ String before = tmp.substring(0, open - 1);
+ String after = tmp.substring(close + 1);
+ tmp = before + (minTerm(sub, input)) + after;
+ }
+
+ return minTerm(tmp, input);
+ }
+ private boolean minTerm(String sub, Data input) throws DataValueNotAvailableException, MalformedBlockConditionException {
+ if (sub.equals("true"))
+ return true;
+ if (sub.equals("false"))
+ return false;
+ if (sub.indexOf("&") >= 0)
+ return minTerm(sub.substring(0, sub.indexOf("&")), input) &&
+ minTerm(sub.substring(sub.indexOf("&") + 1), input);
+ if (sub.indexOf("|") >= 0)
+ return minTerm(sub.substring(0, sub.indexOf("|")), input) ||
+ minTerm(sub.substring(sub.indexOf("|") + 1), input);
+ if (sub.indexOf("^") >= 0)
+ return minTerm(sub.substring(0, sub.indexOf("^")), input) ^
+ minTerm(sub.substring(sub.indexOf("^") + 1), input);
+ if (sub.indexOf("!") >= 0)
+ return ! minTerm(sub.substring(sub.indexOf("!") + 1), input);
+ if (sub.indexOf("==") >= 0)
+ return stringValue(sub.substring(0, sub.indexOf("==")), input).equals(stringValue(sub.substring(sub.indexOf("==") + 1), input));
+ if (sub.indexOf(">") >= 0)
+ return intValue(sub.substring(0, sub.indexOf(">")), input) > intValue(sub.substring(sub.indexOf(">") + 1), input);
+ if (sub.indexOf("<") >= 0)
+ return intValue(sub.substring(0, sub.indexOf("<")), input) < intValue(sub.substring(sub.indexOf("<") + 1), input);
+ if (sub.indexOf(">=") >= 0)
+ return intValue(sub.substring(0, sub.indexOf(">=")), input) >= intValue(sub.substring(sub.indexOf(">=") + 1), input);
+ if (sub.indexOf("<=") >= 0)
+ return intValue(sub.substring(0, sub.indexOf("<=")), input) >= intValue(sub.substring(sub.indexOf("<=") + 1), input);
+ if (sub.indexOf("data") >= 0)
+ return minTerm(getDataValue(sub, input), input);
+
+ throw new MalformedBlockConditionException();
+ }
+
+ private int intValue(String substring, Data input) {
+ try {
+ return Integer.parseInt(substring);
+ } catch (NumberFormatException e) {
+ }
+ try {
+ return Integer.parseInt(getDataValue(substring, input));
+ } catch (NumberFormatException e) {
+ } catch (Exception e) {
+ }
+ throw new NumberFormatException();
+ }
+
+ private String getDataValue(String string, Data input) throws DataValueNotAvailableException {
+ if (string.equals("setup.state"))
+ return ((Setup) input.getEntry("setup")).getState();
+ if (string.indexOf("data.") == 0) {
+ String key = string.substring("data.".length() + 1);
+ if (input.getEntry("blockData") != null) {
+ Map blockData = (Map) input.getEntry("blockData");
+ if (blockData.get(key) != null)
+ return blockData.get(key);
+ }
+ }
+ throw new DataValueNotAvailableException();
+ }
+
+ private String stringValue(String string, Data input) throws DataValueNotAvailableException {
+ if (string.substring(0, 1).equals("\"") && string.substring(string.length() - 1).equals("\""))
+ return string.substring(1, string.length() - 1);
+
+ return getDataValue(string, input);
+ }
+}
diff --git a/src/main/java/net/persei/dionysus/blocks/BlockHelper.java b/src/main/java/net/persei/dionysus/blocks/BlockHelper.java
new file mode 100644
index 0000000..922a16d
--- /dev/null
+++ b/src/main/java/net/persei/dionysus/blocks/BlockHelper.java
@@ -0,0 +1,21 @@
+package net.persei.dionysus.blocks;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import net.persei.dionysus.exceptions.UnexpectedDataTypeException;
+
+public class BlockHelper {
+ static void addPassLog(Data input, String type, Object object) throws UnexpectedDataTypeException {
+ Object obj = input.getEntry(type);
+ List