package com.csound.wizard.model; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.apache.commons.io.FileUtils; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.JSONValue; import android.view.View; import android.view.ViewGroup; import com.csound.wizard.Const; import com.csound.wizard.Utils; import com.csound.wizard.layout.Json; import com.csound.wizard.layout.UnitUtils; import com.csound.wizard.layout.Units; import com.csound.wizard.layout.Units.StatefulUnit; public class TrackState { private HashMap<String,double[]> table; public TrackState(HashMap<String,double[]> t) { table = t; } public TrackState() { table = new HashMap<String,double[]>(); } // decoding/encoding from JSON @SuppressWarnings("unchecked") private String encode() { JSONObject obj =new JSONObject(); for (Map.Entry<String,double[]> entry: table.entrySet()) { JSONArray vals = new JSONArray(); for (double d: entry.getValue()) { vals.add(Double.valueOf(d)); } obj.put(entry.getKey(), vals); } return obj.toJSONString(); } private static TrackState decode(String text) { Object json = JSONValue.parse(text); HashMap<String,double[]> res = new HashMap<String,double[]>(); if (Json.isObject(json)) { JSONObject obj = (JSONObject) json; for (Object it: obj.entrySet()) { Entry<String, Object> entry = (Entry<String, Object>) it; if (Json.isArray(entry.getValue())) { JSONArray arr = (JSONArray) entry.getValue(); double[] vals = new double[arr.size()]; for (int i = 0; i < arr.size(); i++) { Object x = arr.get(i); if (Json.isNumber(x)) { vals[i] = Json.getFloat(x); } else { vals[i] = 0; } } res.put(entry.getKey(), vals); } } } return new TrackState(res); } // saving loading to file public void save(String fileName) throws IOException { FileUtils.write(new File(fileName), encode()); } public static TrackState load(String fileName) throws IOException { String text = FileUtils.readFileToString(new File(fileName), "UTF-8"); return decode(text); } // Map methods public double[] get(String key) { return table.get(key); } public boolean containsKey(String key) { return table.containsKey(key); } public void put(String key, double[] value) { table.put(key, value); } public static TrackState readDefaultState(String track) { Object json; try { InputStream is = FileUtils.openInputStream(new File(track)); json = JSONValue.parse(Utils.getUi(is)); } catch (IOException e) { return new TrackState(); } TrackState res = new TrackState(); res.getStateFromJson(json); return res; } private void getStateFromJson(Object json) { for (String name: Units.arrayUnits) { if (Json.getArray(name, json) != null) { for (Object x: Json.getArray(name, json)) { this.getStateFromJson(x); } return; } } for (String name: Units.singletonArrayUnits) { if (Json.getObject(name, json) != null) { this.getStateFromJson(Json.getObject(name, json)); return; } } if (Json.isArray(json)) { for (Object x: (JSONArray) json) { this.getStateFromJson(x); } return; } for (String name: Units.objectArrayUnits) { if (Json.getArray(name, json) != null) { for (Object x: Json.getArray(name, json)) { if (Json.isObject(x)) { JSONObject y = (JSONObject) x; Set keys = y.keySet(); if (keys.size() > 0) { String key = (String) keys.iterator().next(); this.getStateFromJson(y.get(key)); } } } return; } } if (Json.getJson(Const.INIT, json) != null) { if (Json.getJson(Const.SLIDER, json) != null) { Float initVal = Json.getFloat(Const.INIT, json); if (initVal != null) { this.put(UnitUtils.getUnitId(Json.getJson(Const.SLIDER, json)), toTrackState(initVal)); } } else if(Json.getJson(Const.TOGGLE, json) != null) { Boolean initVal = Json.getBoolean(Const.INIT, json); if (initVal != null) { this.put(UnitUtils.getUnitId(Json.getJson(Const.TOGGLE, json)), toTrackState(initVal)); } } else if (Json.getJson(Const.KNOB, json) != null) { Float initVal = Json.getFloat(Const.INIT, json); if (initVal != null) { this.put(UnitUtils.getUnitId(Json.getJson(Const.KNOB, json)), toTrackState(initVal)); } } else if (Json.getJson(Const.SPINNER, json) != null) { Integer initVal = Json.getInteger(Const.INIT, json); if (initVal != null) { this.put(UnitUtils.getUnitId(Json.getJson(Const.SPINNER, json)), toTrackState(initVal)); } } else if (Json.getJson(Const.INTS, json) != null) { Integer initVal = Json.getInteger(Const.INIT, json); if (initVal != null) { this.put(UnitUtils.getUnitId(Json.getJson(Const.INTS, json)), toTrackState(initVal)); } } else if (Json.getJson(Const.NAMES, json) != null) { Integer initVal = Json.getInteger(Const.INIT, json); if (initVal != null) { this.put(UnitUtils.getUnitId(Json.getJson(Const.NAMES, json)), toTrackState(initVal)); } } else if (Json.getJson(Const.HOR_RADIO, json) != null) { Integer initVal = Json.getInteger(Const.INIT, json); if (initVal != null) { this.put(UnitUtils.getUnitId(Json.getJson(Const.HOR_RADIO, json)), toTrackState(initVal)); } } else if (Json.getJson(Const.VER_RADIO, json) != null) { Integer initVal = Json.getInteger(Const.INIT, json); if (initVal != null) { this.put(UnitUtils.getUnitId(Json.getJson(Const.VER_RADIO, json)), toTrackState(initVal)); } } else if (Json.getJson(Const.CHESS, json) != null) { Entry<Integer,Integer> initVal = Json.getIntegerPair(Const.INIT, json); if (initVal != null) { this.put(UnitUtils.getUnitId(Json.getJson(Const.CHESS, json)), toTrackStateIntegerPair(initVal)); } } else if (Json.getJson(Const.PLANE, json) != null) { Entry<Float,Float> initVal = Json.getFloatPair(Const.INIT, json); if (initVal != null) { this.put(UnitUtils.getUnitId(Json.getJson(Const.PLANE, json)), toTrackStateFloatPair(initVal)); } } else if (Json.getJson(Const.PLANE_X, json) != null) { Entry<Integer,Float> initVal = Json.getIntegerFloatPair(Const.INIT, json); if (initVal != null) { this.put(UnitUtils.getUnitId(Json.getJson(Const.PLANE_X, json)), toTrackStateIntegerFloatPair(initVal)); } } else if (Json.getJson(Const.PLANE_Y, json) != null) { Entry<Integer,Float> initVal = Json.getIntegerFloatPair(Const.INIT, json); if (initVal != null) { this.put(UnitUtils.getUnitId(Json.getJson(Const.PLANE_Y, json)), toTrackStateIntegerFloatPair(initVal)); } } } } private static double[] toTrackState(Float x) { double[] ds = new double[1]; ds[0] = x; return ds; } private static double[] toTrackState(Integer x) { double[] ds = new double[1]; ds[0] = x; return ds; } private static double[] toTrackState(Boolean x) { double[] ds = new double[1]; ds[0] = x ? 1 : 0; return ds; } private static double[] toTrackStateIntegerPair(Entry<Integer,Integer> x) { double[] ds = new double[2]; ds[0] = x.getKey(); ds[1] = x.getValue(); return ds; } private static double[] toTrackStateFloatPair(Entry<Float,Float> x) { double[] ds = new double[2]; ds[0] = x.getKey(); ds[1] = x.getValue(); return ds; } private static double[] toTrackStateIntegerFloatPair(Entry<Integer,Float> x) { double[] ds = new double[2]; ds[0] = x.getKey(); ds[1] = x.getValue(); return ds; } public void saveFromView(View rootView) { updateState(this, rootView); } private static void updateState(TrackState state, View root) { if (root instanceof StatefulUnit) { StatefulUnit unit = (StatefulUnit) root; state.put(unit.getUnitId(), unit.getUnitState()); } else if (root instanceof ViewGroup) { ViewGroup vg = (ViewGroup) root; for (int i = 0; i < vg.getChildCount(); i++) { updateState(state, vg.getChildAt(i)); } } } }