/* Copyright (C) 2004 - 2005  db4objects Inc.  http://www.db4o.com

This file is part of the db4o open source object database.

db4o is free software; you can redistribute it and/or modify it under
the terms of version 2 of the GNU General Public License as published
by the Free Software Foundation and as clarified by db4objects' GPL 
interpretation policy, available at
http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
Suite 350, San Mateo, CA 94403, USA.

db4o is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */
namespace com.db4o.test.net2
{
#if NET_2_0
	using System;
	using System.Collections.Generic;
	using System.Text;
	using com.db4o;
	using com.db4o.test;
	using com.db4o.query;

	class Task
	{
		public string name;

		public Task(string name)
		{
			this.name = name;
		}
	}

	class Project
	{
		public string name;
		public List<Task> tasks;

		public Project(string name)
		{
			this.name = name;
			this.tasks = new List<Task>();
		}
	}

	class Net2GenericContainers
	{
		public void store()
		{
			Project p1 = new Project("db4o");
			p1.tasks.Add(new Task("dotnet 2 generics"));
			p1.tasks.Add(new Task("clean mono build"));
			
			Project p2 = new Project("enlightenment");
			p2.tasks.Add(new Task("meditate"));

			Tester.store(p1);
			Tester.store(p2);

            Dictionary<string, List<Task>> dict = new Dictionary<string, List<Task>>();
            dict.Add(p1.name, p1.tasks);
            dict.Add(p2.name, p2.tasks);

            Tester.store(dict);
			
			Tester.reOpenAll();
		}
		
		public void testDescendOnList()
		{
			ensureProjectByTaskName("enlightenment", "meditate");
			ensureProjectByTaskName("db4o", "clean mono build");
		}

		private static void ensureProjectByTaskName(string expectedProjectName, string taskName)
		{
			Query q = Tester.query();
			q.constrain(typeof (Project));
			q.descend("tasks").descend("name").constrain(taskName);
			ObjectSet result = q.execute();
			Tester.ensureEquals(1, result.Count, "testDescendOnList.Count");
			Tester.ensureEquals(expectedProjectName, ((Project) result[0]).name, "testDescendOnList.name");
		}


		public void testDict()
        {
            Query query = Tester.query();
            query.constrain(typeof(Dictionary<string, List<Task>>));

            ObjectSet os = query.execute();
            Tester.ensureEquals(1, os.size());

            Dictionary<string, List<Task>> dict = (Dictionary<string, List<Task>>)os.next();
            Tester.ensure(dict != null);

            Tester.ensureEquals(2, dict.Count);
            Tester.ensure(dict.ContainsKey("enlightenment"));
            Tester.ensure(dict.ContainsKey("db4o"));
        }

		public void testProjects()
		{
			Query query = Tester.query();
			query.constrain(typeof(Project));
			query.descend("name").orderAscending();

			ObjectSet os = query.execute();
			Tester.ensureEquals(2, os.size());

			Project p = (Project)os.next();
			Tester.ensureEquals("db4o", p.name);
			Tester.ensure(p.tasks != null);
			Tester.ensureEquals(2, p.tasks.Count);
			Tester.ensureEquals("dotnet 2 generics", p.tasks[0].name);
			Tester.ensureEquals("clean mono build", p.tasks[1].name);

			p = (Project)os.next();
			Tester.ensureEquals("enlightenment", p.name);
			Tester.ensure(p.tasks != null);
			Tester.ensureEquals(1, p.tasks.Count);
			Tester.ensureEquals("meditate", p.tasks[0].name);
		}

		public void testTasks()
		{
			Query query = Tester.query();
			query.constrain(typeof(Task));
			query.descend("name").orderAscending();

			ObjectSet os = query.execute();
			Tester.ensureEquals(3, os.size());
			foreach (string expected in new string[] { "clean mono build", "dotnet 2 generics", "meditate" })
			{
				Tester.ensureEquals(expected, ((Task)os.next()).name);
			}
		}

		public void testTaskLists()
		{
			Query query = Tester.query();
			query.constrain(typeof(List<Task>));

			Tester.ensureEquals(2, query.execute().size());

			query = Tester.query();
			query.constrain(typeof(List<Project>));

			Tester.ensureEquals(0, query.execute().size());
		}
	}
#endif
}
