/*
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.

 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

/*
  <file> UlsStream.cpp </file>
  <brief>
  </brief>
  <author>
    Stanley Hong <link2next@gmail.com>, April 2017.
  </author>
*/
#pragma once

#include "UlsFactory.h"

using namespace System;
using namespace System::Collections::Generic;

namespace uls {
	namespace polaris {
		
		//
		// UlsTmplList
		//
		public ref class UlsTmplList
		{
			static UlsFactory ^uf;
			static UlsTmplList();

			bool isDisposed;
			Dictionary<String^, String^> ^hash_tbl;
			void init_uls_tmpllist(int size);

		public:
			// <brief>
			// UlsTmplList is to store a list of template variables and their values.
			// Notice that a template variable is composed of a name and its (string) value.
			// It can be passed to the argument of UlsIStream().
			// </brief>
			// <parm name="size">The capacity of the internal list.</parm>
			UlsTmplList(int size);
			UlsTmplList();
			virtual ~UlsTmplList();

			// <brief>
			// This clears the internal list of variables. The length of the list will be zero.
			// </brief>
			// <return>none</return>
			void clear();

			// <brief>
			// Checks if the variable 'tnam' exists in the list.
			// </brief>
			// <return>true/false</return>
			bool exist(String ^nam);

			// <brief>
			// It returns the length of the internal list. It's less than or equal to the capacity of the list.
			// </brief>
			// <return># of variables</return>
			int length();

			// <brief>
			// Append a pair <tnam, tval> to the list increasing the length of the list.
			// </brief>
			// <parm name="tnam">the name of template variable</parm>
			// <parm name="tval">the value of the 'tnam'</parm>
			// <return>none</return>
			void add(String ^nam, String ^val);

			// <brief>
			// It returns the value of 'tnam'.
			// If there is no template variable named 'tnam', it returns 'null'.
			// </brief>
			// <parm name="tnam">the name of template variable</parm>
			// <return>the value of the 'tnam'</return>
			String ^getValue(String ^nam);

			// <brief>
			// This modifies the pair <tnam, tval> in the internal list if the item named 'tnam' exists.
			// </brief>
			// <parm name="tnam">the name of template variable</parm>
			// <parm name="tval">the value of the 'tnam'</parm>
			// <return>true/false</return>
			bool setValue(String ^nam, String ^val);

			// <brief>
			// This exports the internal list to another UlsTmplList object.
			// </brief>
			// <return>Opaque Data</return>
			// <brief>
			// Export the internal list to another UlsTmplList object.
			// </brief>
			// <parm name="tmpl_list_exp">A new UlsTmplList object to which the current list is exported.</parm>
			// <return>the length of the list</return>
			UlsFactory::uls_tmpl_list_t ^exportTmpls();

			// <brief>
			// Dumps the internal list of pairs <tnam,tval> to stdout.
			// </brief>
			// <return>none</return>
			void dump();
		};

		public ref class UlsStream : UlsObject {
			static UlsStream();

		protected:
			static UlsFactory ^uf;
			bool read_only;

		public:
            // <brief>
            // A Constructor of 'UlsStream'
            // </brief>
            // <parm name="lex">The analyzer associated with this 'UlsStream'</parm>
			UlsStream(bool rdonly);
			UlsStream();
		};
	}
}
