// Path: traction/src/main/java/traction/mvc/implementations/CommandArgument.java
// public class CommandArgument
// {
//     private String commandName;
//     private boolean eventCancelled;
//     private JSONObject tagProperties;
// 
//     public boolean isEventCancelled()
//     {
//         return eventCancelled;
//     }
// 
//     public void setEventCancelled(boolean isCancelled)
//     {
//         eventCancelled = isCancelled;
//     }
// 
//     public CommandArgument(String commandName)
//     {
//         this(commandName, null);
//     }
// 
//     public CommandArgument(String commandName, JSONObject tagProperties)
//     {
//         this.commandName = commandName;
//         this.eventCancelled = false;
//         this.tagProperties = tagProperties;
//     }
// 
//     public JSONObject getEventData()
//     {
//         return tagProperties;
//     }
// 
//     public String getCommandName()
//     {
//         return commandName;
//     }
// }
// 
// Path: traction/src/main/java/traction/mvc/implementations/PathBinding.java
// public class PathBinding
// {
// 	private final ArrayList<IUIElement<?>> uiElements = new ArrayList<IUIElement<?>>();
// 
// 	/**
// 	 * Adds a ui element to the Path biding
// 	 * @param element
// 	 */
// 	public void addUIElement(IUIElement<?> element)
// 	{
// 		uiElements.add(element);
// 	}	
// 	
// 	/**
// 	 * Gets all ui elements tracked to this path so far
// 	 * @return
// 	 */
// 	public ArrayList<IUIElement<?>> getUIElements()
// 	{
// 		return uiElements;
// 	}
// }
// 
// Path: traction/src/main/java/traction/mvc/interfaces/IPropertyStore.java
// public interface IPropertyStore
// {
//     Property<?,?> getProperty(String name);
// }
// 
// Path: traction/src/main/java/traction/mvc/interfaces/IObservableCommand.java
// public interface IObservableCommand
// extends IObservableObject
// {
//     /**
//      * call to execute command
//      * @param arg
//      */
//     void execute(CommandArgument arg);
// 
//     void setExecuteListener(IOnExecuteListener listener);
// 
//     /**
//      *
//      * @return : true if command can execute
//      */
//     boolean getCanExecute();
// 
//     /**
//      * set whether command can execute
//      * @param b
//      */
//     void setCanExecute(boolean b);
// }
// 
// Path: traction/src/main/java/traction/mvc/interfaces/IPOJO.java
// public interface IPOJO
// {
//     /**
//      * Access property from property store.
//      * @param name
//      * @return if property exists, return property object, or null if not found
//      */
//     Property<Object,Object> getProperty(String name);
// }
// 
// Path: traction/src/main/java/traction/mvc/interfaces/IUIElement.java
// public interface IUIElement<T>
// {
// 	/**
// 	 * sets a handler for when the ui recieves data from the model/view-model
// 	 * @param listener
// 	 */
// 	public void setUIUpdateListener(IUIUpdateListener<T> listener);
// 
// 	/**
// 	 * Sends data to the ui element. Expects the IUIUpdateListener to be called 
// 	 * @param value
// 	 */
// 	public void receiveUpdate(final Object value);
// 	
// 	/**
// 	 * Sends data from ui back to model/view-model
// 	 * @param value
// 	 */
// 	public void sendUpdate(T value);
// 
// 	/**
// 	 * Initializes data for ui element during inflation
// 	 */
// 	public void initialize() throws Exception;
// 
// 	/**
// 	 * gets the binding inventory the ui element is associated to
// 	 * @return
// 	 */
// 	public BindingInventory getBindingInventory();
// 
// 	/**
// 	 * listener to handle updates to the ui element
// 	 * @author Tim Stratton
// 	 *
// 	 * @param <S> : type of data sent to ui element
// 	 */
// 	public interface IUIUpdateListener<S>
// 	{
// 		public void onUpdate(S value);
// 	}
// 
//     public boolean isDefined();
// 
//     public void track(BindingInventory differentBindingInventory);
// }


import traction.mvc.interfaces.IUIElement;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.NavigableMap;
import java.util.Set;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.util.Property;
import traction.mvc.implementations.CommandArgument;
import traction.mvc.implementations.PathBinding;
import traction.mvc.interfaces.IPropertyStore;
import traction.mvc.interfaces.IObservableCommand;
import traction.mvc.interfaces.IPOJO;
/* Copyright 2013 Tim Stratton

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */

package traction.mvc.observables;



/**
 * Tracks all ui element and the property paths to the model's data, also delegates to and from the view and the model/view-model.
 * Pretty much the most important class in this library.
 * @author Tim Stratton
 *
 */
public class BindingInventory
    extends ObservableObject
{
	/**
	 * patterns for parsing property chains
	 */
	private final static Pattern pathPattern = Pattern.compile("(\\\\|[\\.]*)(.+)");
	private final static Pattern split = Pattern.compile("\\.");

	//used for determining a range of paths to get from the inventory. Useful for getting all properties down a 
	//specific branch
	private final static String pathTerminator = "{";
	
	//current context object, may be the view model or model
	private IProxyObservableObject context;
	private Object nonObservableContext;

	//there may be many levels of inventories, this points to the parent inventory. will be null if it is the root
	private BindingInventory parentInventory;

// Path: traction/src/main/java/traction/mvc/implementations/CommandArgument.java
// public class CommandArgument
// {
//     private String commandName;
//     private boolean eventCancelled;
//     private JSONObject tagProperties;
// 
//     public boolean isEventCancelled()
//     {
//         return eventCancelled;
//     }
// 
//     public void setEventCancelled(boolean isCancelled)
//     {
//         eventCancelled = isCancelled;
//     }
// 
//     public CommandArgument(String commandName)
//     {
//         this(commandName, null);
//     }
// 
//     public CommandArgument(String commandName, JSONObject tagProperties)
//     {
//         this.commandName = commandName;
//         this.eventCancelled = false;
//         this.tagProperties = tagProperties;
//     }
// 
//     public JSONObject getEventData()
//     {
//         return tagProperties;
//     }
// 
//     public String getCommandName()
//     {
//         return commandName;
//     }
// }
// 
// Path: traction/src/main/java/traction/mvc/implementations/PathBinding.java
// public class PathBinding
// {
// 	private final ArrayList<IUIElement<?>> uiElements = new ArrayList<IUIElement<?>>();
// 
// 	/**
// 	 * Adds a ui element to the Path biding
// 	 * @param element
// 	 */
// 	public void addUIElement(IUIElement<?> element)
// 	{
// 		uiElements.add(element);
// 	}	
// 	
// 	/**
// 	 * Gets all ui elements tracked to this path so far
// 	 * @return
// 	 */
// 	public ArrayList<IUIElement<?>> getUIElements()
// 	{
// 		return uiElements;
// 	}
// }
// 
// Path: traction/src/main/java/traction/mvc/interfaces/IPropertyStore.java
// public interface IPropertyStore
// {
//     Property<?,?> getProperty(String name);
// }
// 
// Path: traction/src/main/java/traction/mvc/interfaces/IObservableCommand.java
// public interface IObservableCommand
// extends IObservableObject
// {
//     /**
//      * call to execute command
//      * @param arg
//      */
//     void execute(CommandArgument arg);
// 
//     void setExecuteListener(IOnExecuteListener listener);
// 
//     /**
//      *
//      * @return : true if command can execute
//      */
//     boolean getCanExecute();
// 
//     /**
//      * set whether command can execute
//      * @param b
//      */
//     void setCanExecute(boolean b);
// }
// 
// Path: traction/src/main/java/traction/mvc/interfaces/IPOJO.java
// public interface IPOJO
// {
//     /**
//      * Access property from property store.
//      * @param name
//      * @return if property exists, return property object, or null if not found
//      */
//     Property<Object,Object> getProperty(String name);
// }
// 
// Path: traction/src/main/java/traction/mvc/interfaces/IUIElement.java
// public interface IUIElement<T>
// {
// 	/**
// 	 * sets a handler for when the ui recieves data from the model/view-model
// 	 * @param listener
// 	 */
// 	public void setUIUpdateListener(IUIUpdateListener<T> listener);
// 
// 	/**
// 	 * Sends data to the ui element. Expects the IUIUpdateListener to be called 
// 	 * @param value
// 	 */
// 	public void receiveUpdate(final Object value);
// 	
// 	/**
// 	 * Sends data from ui back to model/view-model
// 	 * @param value
// 	 */
// 	public void sendUpdate(T value);
// 
// 	/**
// 	 * Initializes data for ui element during inflation
// 	 */
// 	public void initialize() throws Exception;
// 
// 	/**
// 	 * gets the binding inventory the ui element is associated to
// 	 * @return
// 	 */
// 	public BindingInventory getBindingInventory();
// 
// 	/**
// 	 * listener to handle updates to the ui element
// 	 * @author Tim Stratton
// 	 *
// 	 * @param <S> : type of data sent to ui element
// 	 */
// 	public interface IUIUpdateListener<S>
// 	{
// 		public void onUpdate(S value);
// 	}
// 
//     public boolean isDefined();
// 
//     public void track(BindingInventory differentBindingInventory);
// }


// Path: traction/src/main/java/traction/mvc/observables/BindingInventory.java
import traction.mvc.interfaces.IUIElement;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.NavigableMap;
import java.util.Set;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.util.Property;
import traction.mvc.implementations.CommandArgument;
import traction.mvc.implementations.PathBinding;
import traction.mvc.interfaces.IPropertyStore;
import traction.mvc.interfaces.IObservableCommand;
import traction.mvc.interfaces.IPOJO;

/* Copyright 2013 Tim Stratton

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */

package traction.mvc.observables;



/**
 * Tracks all ui element and the property paths to the model's data, also delegates to and from the view and the model/view-model.
 * Pretty much the most important class in this library.
 * @author Tim Stratton
 *
 */
public class BindingInventory
    extends ObservableObject
{
	/**
	 * patterns for parsing property chains
	 */
	private final static Pattern pathPattern = Pattern.compile("(\\\\|[\\.]*)(.+)");
	private final static Pattern split = Pattern.compile("\\.");

	//used for determining a range of paths to get from the inventory. Useful for getting all properties down a 
	//specific branch
	private final static String pathTerminator = "{";
	
	//current context object, may be the view model or model
	private IProxyObservableObject context;
	private Object nonObservableContext;

	//there may be many levels of inventories, this points to the parent inventory. will be null if it is the root
	private BindingInventory parentInventory;

	private final TreeMap<String, PathBinding> map = new TreeMap<String, PathBinding>();