using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Castle.ActiveRecord.Framework;
using Castle.ActiveRecord.Framework.Config;
using Castle.ActiveRecord;
using System.Reflection;
using Castle.ActiveRecord.Queries;
using System.Collections;
using NHibernate;
using NHibernate.Criterion;

namespace Quering1Example
{
    class Program
    {
        static void Main( string[] args )
        {
            IConfigurationSource source = ActiveRecordSectionHandler.Instance;
            ActiveRecordStarter.Initialize( Assembly.GetAssembly( typeof( Program ) ), source );
            ActiveRecordStarter.DropSchema();
            ActiveRecordStarter.CreateSchema();

            var j1 = new Jednostka { Nazwa = "Wrocław" };
            var j2 = new Jednostka { Nazwa = "Kraków" };
            var j3 = new Jednostka { Nazwa = "Warszawa" };
            var j4 = new Jednostka { Nazwa = "Moskwa" };
            var j5 = new Jednostka { Nazwa = "Nowy Jork" };
            var j6 = new Jednostka { Nazwa = "Londyn" };

            var o1 = new Osoba { ImieNazwisko = "Jan Kowalski" };
            var o2 = new Osoba { ImieNazwisko = "Marian Wolny" };
            var o3 = new Osoba { ImieNazwisko = "Janina Zapotoczna" };
            var o4 = new Osoba { ImieNazwisko = "Alfred Nowak" };
            var o5 = new Osoba { ImieNazwisko = "Alicja Cicha" };
            var o6 = new Osoba { ImieNazwisko = "Maja Klin" };

            j1.L_Osoba.Add( o1 ); j1.L_Osoba.Add( o2 );
            j2.L_Osoba.Add( o3 ); j2.L_Osoba.Add( o4 );
            j3.L_Osoba.Add( o5 ); j3.L_Osoba.Add( o6 );

            j1.Save(); j2.Save(); j3.Save(); j4.Save(); j5.Save(); j6.Save();

            for ( int i=0; i<500; ++i )
                ( new Osoba { ImieNazwisko = "Iwan Ponyriow"+i.ToString(), Jednostka = j4 } ).Save();
            for ( int i=0; i<500; ++i )
                ( new Osoba { ImieNazwisko = "John Preston"+i.ToString(), Jednostka = j5 } ).Save();
            for ( int i=0; i<500; ++i )
                ( new Osoba { ImieNazwisko = "Sherlock Holmes"+i.ToString(), Jednostka = j6 } ).Save();

            {
                Console.WriteLine( "1. ----------------" );
                ICriterion[] criteria = { Expression.Like( "ImieNazwisko", "M%" ), Expression.In( "Jednostka.ID", new int[] { 1, 2 } ) };
                var osoby = Osoba.FindAll( criteria );
                foreach ( var o in osoby )
                    Console.WriteLine( o.ImieNazwisko + " " + o.Jednostka.Nazwa );
            }

            {
                Console.WriteLine( "2. ----------------" );
                ICriterion[] criteria = { Expression.Like( "ImieNazwisko", "M%" ), Expression.In( "Jednostka.ID", new int[] { 1, 2 } ) };
                var osoby = Osoba.FindAll( criteria );
                foreach ( var o in osoby )
                    Console.WriteLine( o.ImieNazwisko + " " + o.Jednostka.Nazwa );
            }

            {
                Console.WriteLine( "3. ----------------" );
                var q = new SimpleQuery<Osoba>( "from Osoba o where ID between :start and :stop" );
                q.SetParameter( "start", 5 );
                q.SetParameter( "stop", 6 );
                var SimpleQuery = q.Execute();
                foreach ( Osoba o in SimpleQuery )
                    Console.WriteLine( o.ImieNazwisko + " " + o.Jednostka.Nazwa );
            }

            {
                Console.WriteLine( "4. ----------------" );
                var q = new HqlBasedQuery( typeof( Osoba ), "from Osoba o inner join o.Jednostka where o.ImieNazwisko like 'Jo%' or o.ImieNazwisko like 'Sh'" );
                q.SetQueryRange( 20, 5 );
                var Result = (ArrayList)Osoba.ExecuteQuery( q );
                foreach ( var o in Result )
                    Console.WriteLine( ( ( o as object[] )[0] as Osoba ).ImieNazwisko + " " + ( ( o as object[] )[1] as Jednostka ).Nazwa );
            }

            {
                Console.WriteLine( "5. ----------------" );
                var q = new ScalarQuery<int>( typeof( Osoba ), @"select max(o.ID) from Osoba o" );
                Console.WriteLine( "Max ID: "+q.Execute().ToString() );
            }

            {
                Console.WriteLine( "6. ----------------" );
                ICriterion ic = Expression.Like( "Nazwa", "W%" );
                DetachedCriteria dc = DetachedCriteria.For<Osoba>().CreateCriteria( "Jednostka" ).Add( ic );
                foreach ( var o in Osoba.FindAll( dc ) )
                    Console.WriteLine( o.ImieNazwisko );
            }

            {
                Console.WriteLine( "7. ----------------" );
                //ICriterion[] criteria = { Expression.Like( "Jednostka.Nazwa", "W%" ) };
                ICriterion[] criteria = { Expression.Like( "ImieNazwisko", "Ma%" ) };
                ActiveRecordCriteriaQuery q = new ActiveRecordCriteriaQuery( typeof( Osoba ), criteria );
                var lista = (ArrayList)ActiveRecordMediator.ExecuteQuery( q );
                foreach ( Osoba o in lista )
                    Console.WriteLine( o.ImieNazwisko );
            }

            {
                Console.WriteLine( "8. ----------------" );
                ISession session = ActiveRecordMediator.GetSessionFactoryHolder().CreateSession( typeof( Osoba ) );
                var result = session.CreateQuery( "from Osoba o where o.Jednostka.Nazwa like ?" )
                    .SetParameter( 0, "W%" )
                    .List<Osoba>();
                foreach ( var o in result )
                    Console.WriteLine( o.ImieNazwisko );

            }

            Console.ReadLine();
        }
    }
}
