/* 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 com.db4o.ext;

    public class Net2GenericOtherCollections
    {
        public void store()
        {
            CHolder ch = new CHolder();
            ch.CreateCollections();
            Tester.store(ch);
        }

        public void test()
        {
            CHolder ch = QueryHolder();
            ch.TestBeforeUpdate();
            ch.Update();
            Tester.reOpen();
            ch = QueryHolder();
            ch.TestAfterUpdate();
        }

        private CHolder QueryHolder()
        {
            return Tester.objectContainer().query<CHolder>(typeof(CHolder))[0];
        }

    }

    public class CHolder
    {
        LinkedList <CItem> linkedList;
        Queue<CItem> queue;
        SortedDictionary<CItem,string> sortedDictionary;
        SortedList<CItem,string> sortedList;
        Stack<CItem> stack;

        public void CreateCollections()
        {
            linkedList = new LinkedList<CItem>();
            for(int i = 0; i < 10; i++)
            {
                linkedList.AddLast(new CItem("ll" + i));
            }

            queue = new Queue<CItem>();
            for (int i = 0; i < 10; i++)
            {
                queue.Enqueue(new CItem("q" + i));
            }

            sortedDictionary = new SortedDictionary<CItem, string>();
            for (int i = 0; i < 10; i++)
            {
                sortedDictionary.Add(new CItem("sd" + i), "sd" + i);
            }

            sortedList = new SortedList<CItem,string>();
            for (int i = 0; i < 10; i++)
            {
                sortedList.Add(new CItem("sl" + i), "sl" + i);
            }

            stack = new Stack<CItem>();
            for (int i = 0; i < 10; i++)
            {
                stack.Push(new CItem("st" + i));
            }

        }

        public void TestBeforeUpdate()
        {
            ExtObjectContainer oc = Tester.objectContainer();

            Tester.ensure(linkedList.Last.Value.Equals(new CItem("ll9")));

            for (int i = 0; i < 10; i++)
            {
                Tester.ensure(queue.Dequeue().Equals(new CItem("q" + i)));
            }

            // Sorted dictionary needs explicit activation since it uses a TreeSet underneath.
            oc.activate(sortedDictionary, int.MaxValue);
            for (int i = 0; i < 10; i++)
            {
                Object obj = sortedDictionary[new CItem("sd" + i)];
                Tester.ensure(obj.Equals("sd" + i));
            }

            for (int i = 0; i < 10; i++)
            {
                Tester.ensure(sortedList[new CItem("sl" + i)].Equals("sl" + i));
            }

            for (int i = 9; i >= 0; i--)
            {
                Tester.ensure(stack.Pop().Equals(new CItem("st" + i)));
            }

        }

        public void Update()
        {
            ObjectContainer oc = Tester.objectContainer();
            
            linkedList.AddLast(new CItem("update"));
            oc.set(linkedList);

            queue.Enqueue(new CItem("update"));
            oc.set(queue);

            sortedDictionary.Add(new CItem("update"), "update");
            oc.set(sortedDictionary);

            sortedList.Add(new CItem("update"), "update");
            oc.set(sortedList);

            stack.Push(new CItem("update"));
            oc.set(stack);
        }

        public void TestAfterUpdate()
        {
            Tester.ensure(linkedList.Last.Value.Equals(new CItem("update")));

            Tester.ensure(queue.Dequeue().Equals(new CItem("update")));

            Tester.ensure(sortedList[new CItem("update")].Equals("update"));

            Tester.ensure(stack.Pop().Equals(new CItem("update")));

        }

    }

    public class CItem : IComparable
    {
        string _name;

        public CItem()
        {
        }

        public CItem(string name)
        {
            _name = name;
        }

        public override int GetHashCode()
        {
            return _name.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return false;
            }

            CItem other = obj as CItem;

            if (other == null)
            {
                return false;
            }

            return _name.Equals(other._name);
        }

        public string Name()
        {
            return _name;
        }

        public int CompareTo(Object other)
        {
            CItem otherCItem = other as CItem;
            return _name.CompareTo(otherCItem._name);
        }
    }
#endif
}
