// clsSearch.cs
// Copyright (C) 2008 Karel Jordaan karel_jordaan@yahoo.com.au
// 
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// This program 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
using System;
using System.Windows.Forms;
using System.Diagnostics;
using System.Data;
using System.Collections;
using FileScope.Gnutella2;
using FileScope;
using GUIControlLogic.Error;
using ZANZI.Test;
using ZANZIClient;
using ZANZILib.Protocols.QueryCriteria;
using ZANZILib.Protocols.ResultOne;
using ZANZILib.Protocols;
using LibControlLogic;


using System.Xml;
using System.Xml.Serialization;
using System.IO;

namespace GUIControlLogic
{
    /// <summary>
    /// Summary description for clsSearch.
    /// </summary>
    /// <remarks>None</remarks>
    public class clsSearch
    {
        #region Variable declaration

        /// <summary>
        /// Reference to the search frm in the client
        /// </summary>
        /// <remarks>None</remarks>
        private readonly frmSearch m_frm;

        private readonly clsXML m_xml = new clsXML();
        private string XMLSearchString ;

        #endregion

        #region Structures

        #endregion

        #region Functions

        /// <summary>Main entry for clsSearch</summary>
        /// <returns>Returns nothing</returns>
        /// <param name="frm">Used to pass the MDIParent as reference</param>
        /// <remarks>clsSearch is the constructor for the clsSearch class.  
        /// The <paramref name="frm"/> parameter takes a reference to frmMain.
        /// The <paramref name="cls"/> parameter takes a reference to frmMain.
        /// The <paramref name="trv"/> parameter takes a reference to frmMain's Treeview.
        /// <c>public clsSearch(clsMain cls, clsTreeView trv)</c>
        /// <c>public clsSearch(clsSearch frm)</c>
        /// 
        /// <summary>Main entry for clsSearch</summary>
        /// <returns>Takes no variables and returns nothing</returns>
        ///<c>public clsSearch()</c>
        public clsSearch(frmSearch frm)
        {

            //zzoi 28Feb 2009
            try
            {
                //we need this to set the current selected record lateron
                m_frm = frm;


                //register for events
                GUIBridge.G2QueryHitEvent += G2QueryHit;

            }
            catch (Exception ex)
            {
                new clsExeption(ex);
                //ErrByte = 1;
            }
        }

        /// <summary>
        /// Init a search for objects on the network
        /// </summary>
        /// <param name="grd">The grid that will display results.</param>
        /// <remarks>None</remarks>
        public void DoSearch(clsZanziProt objSearchCriteria, DataGrid grd)
        {
            //Pass the query object to the server

            //test loopback data
            clsTest cls = new clsTest();

            //zzoi 1Mrt 2009 ignore the test data while testing G2 return query hit
            //grd.DataSource = cls.GetResultPaneTestData();
            //grdResultOne


            //zzoi 8june 2008 serialize the object to xml or binary and send as string to search
            XMLSearchString = m_xml.SerializeXMLObject(objSearchCriteria);
            //zzoi 1mrt 2009 add the search string to the tabpage container ctrl
            m_frm.Tag = XMLSearchString;
            //Search.BeginSearch(m_xml.SerializeXMLObject(objSearchCriteria));
            Search.BeginSearch(XMLSearchString);
            //FileScope.Gnutella2.Search.BeginSearch("test");
        }

        /// <summary>
        /// Downloads the selected file
        /// </summary>
        public void DoDownloadFile()
        {
            //zzoi 10 mrt 2009
            //get the currently selected zprot dataobject
            ArrayList all = ((ArrayList)m_frm.grdResultOne.DataSource);
            //clsZanziProtResultOne itm = (clsZanziProtResultOne) all[m_frm.grdResultOne.CurrentRowIndex];
            clsZanziProtResultOne itm = (clsZanziProtResultOne)all[0];
            QueryHitTable tbl = (QueryHitTable)itm.zqht;

            //start the download
            DownloadManager.NewDownload(tbl);

        }


        /// <summary>
        /// Sync the selected cell with the selected row
        /// </summary>
        /// <param name="grd">A reference to the results data grid</param>
        /// <remarks>None</remarks>
        public void grdResultCurrentCellChanged(DataGrid grd)
        {
            ////long lngID;

            //grd.Select(grd.CurrentRowIndex);

            ////get the row GUID from datacollection 
            ////update frmSearch so that mdiparent can call tool funtions on 
            ////selected record

            //clsTest clsTest = new clsTest();

            ////m_frm.m_CurrentResultRecordGUID = lngID;
            //m_frm.m_CurrentResultRecordGUID = clsTest.GetCurrentSelectedRecordGUI();

            ////TODO: hierdie data moet ook in die propertygrid kan kom
            ////update the global variable for mdi access
            ////Get the underlying datasources record object
            //m_frm.m_ResultOneObj = clsTest.GetSingleResultOneTestData();
        }

        /// <summary>
        /// None
        /// </summary>
        /// <param name="lst">The listview object to display results in</param>
        /// <param name="crit">The ctiretia object for the search</param>
        /// <remarks>None</remarks>
        public void grdResultClick(ListView lst, clsZanziProt crit)
        {
            //determine on what row we are

            //Get the underlying datasources record id

            //retrive the characteristics object

            //fill the list with characteristics


            //testdata

            //zzoi  23Feb 2009
            //for testing purposes create a resultset on the other node
            //and send it back as results queryhit
            //therefore comment stub here

            //clsTest clsTest = new clsTest();
            //clsTest.GetCharacteristicsTestData(lst);

            //show the list
            lst.Visible = true;
        }

        //zzoi 1Mrt 2009
        /// <summary>
        /// Revieving a Zanzi QueryHit from another node
        /// </summary>
        /// <param name="qho">Queryhit Object</param>
        /// <param name="qht">Queryhit Tabke</param>
        /// <param name="searchName">The search string that resulted in this queryhit</param>
        public void G2QueryHit(QueryHitObject qho, QueryHitTable qht,  string searchName)
        {
            try
            {

                //get the correct frm search
                frmSearch frmS = GetSearchFrm(searchName);


                //get the search frm grid ref
                //grd.DataSource = cls.GetResultPaneTestData();
                object obj;
                ZanziProtResultCollection zrescoll= new ZanziProtResultCollection();
                ArrayList al = new ArrayList();
               // DataRow row = new DataRow() ;
                DataTable dtbl = new DataTable();

                obj = zrescoll;
                obj = m_xml.DeserializeXMLObject(qho.xml,obj);

                zrescoll = (ZanziProtResultCollection)obj;


                ////if (m_frm.grdResultOne.DataSource != null)
                //if (frmS.grdResultOne.DataSource != null)
                //{

                //    // there are zanziprot arraylist items in the source already
                //    //cast to correct type and add results
                //    for(int i=0;i < zrescoll.Count;i++)
                //    {
                //        //invoke correct search from and delegate the task of adding row to grid
                //        //((ArrayList)m_frm.grdResultOne.DataSource).Add(zrescoll[i]);
                //        tabPage.BeginInvoke(new SearchTabPage.addNewItem(tabPage.AddNewItem), new object[] { qho, qht });
                //    }

                //}
                //else //empty datasource
                //{

                //    //no type in datasource
                //    //user arraylist

                //    for (int i = 0; i < zrescoll.Count; i++)
                //    {
                //        al.Add(zrescoll[i]);
                //    }

                //    //invoke correct search from and delegate the task of adding row to grid
                //    //m_frm.grdResultOne.DataSource = al;
                //    tabPage.BeginInvoke(new SearchTabPage.addNewItem(tabPage.AddNewItem), new object[] { qho, qht });
                //}


                
                
                    //cast to correct type and add results
                    for (int i = 0; i < zrescoll.Count; i++)
                    {
                        //invoke correct search from and delegate the task of adding row to grid
                        //((ArrayList)m_frm.grdResultOne.DataSource).Add(zrescoll[i]);

                        //zzoi 10 mrt 2009 add the qho object to the tag for downloads
                        //zrescoll[i].zqht = qht;
                        zrescoll[i].zqht = ProcessQueryHit(qht,qho);
                        frmS.BeginInvoke(new frmSearch.addNewItem(frmS.AddNewItem), new object[] { zrescoll[i] });
                    }

                

                //m_frm.grdResultOne.Refresh();

                #region devcode
                //al.Add(obj);
                
                //dtbl.Rows.Add(obj);

                //XmlSerializer xs = new XmlSerializer(obj.GetType());
                //StringReader stringReader = new StringReader(qho.xml);

                //dtbl.ReadXml(stringReader);
                //dtbl.Merge
                

                //row.ItemArray = al.ToArray ();
                //row.ta
                //((DataTable)m_frm.grdResultOne.DataSource).Rows.Add(row);
                //((DataTable)m_frm.grdResultOne.DataSource).Rows.Add(al.ToArray());


                //al = (ArrayList)obj;
                

                //if (((DataTable)m_frm.grdResultOne.DataSource) != null)
                //{

                //    al = (ArrayList)obj;
                //    //add to the data
                //    foreach (clsZanziProtResultOne row in al)
                //    {
                //        ((DataTable)m_frm.grdResultOne.DataSource).Rows.Add(row);
                //    }
                //}
                //else //empty datasource
                //{
                //    m_frm.grdResultOne.DataSource = al;
                //}
                //((DataTable)m_frm.grdResultOne.DataSource).Merge(


                //((DataTable)m_frm.grdResultOne.DataSource).Rows.Add(m_xml.DeserializeXMLObject(qho.xml, obj));

                //deserialize the hit.xml
                //add the hit xml to the result grid list
                //add the qho to the tag of the row for download pruposes
                //

                #endregion


                Debug.WriteLine("Got queryhit clientside");
            }
            catch (Exception )
            {
                //new clsExeption(ex);
                //ErrByte = 1;
            }

        }
        /// <summary>
        /// Add a QueryThitTable if not exist
        /// </summary>
        /// <param name="qht"></param>
        /// <param name="qho"></param>
        /// <returns></returns>
        public object ProcessQueryHit(QueryHitTable qht,QueryHitObject qho)
        {
            //create the QueryHitTable we will embed into the ListViewItem's tag
            QueryHitTable qhTable = new QueryHitTable();
            if (qht == null)
            {
                qhTable.address = qho.ip.ToString() + ":" + qho.port.ToString();
                qhTable.browse = qho.browse;
                qhTable.busy = qho.busy;
                qhTable.chat = qho.chat;
                qhTable.mp3info = QHOStuff.GetMp3Info(qho);
                qhTable.push = qho.push;
                qhTable.speed = qho.speed;
                qhTable.type = QHOStuff.GetType(qho);
                qhTable.unseenHosts = qho.unseenHosts;
                qhTable.sha1 = QHOStuff.GetSha1Ext(qho);
                qhTable.md4sum = Utils.HexGuid(qho.md4sum);
                //add this singular queryhit to the array of similar queryhits
                qhTable.queryHitObjects.Add(qho);
            }
            else
            {
                qhTable = qht;
            }

            return qhTable;
            
        }


        /// <summary>
        /// Find the correct form based on the search criteria
        /// </summary>
        /// <param name="searchCrit">the search XML</param>
        /// <returns>a frmSearch object</returns>
        public frmSearch GetSearchFrm(string searchCrit)
        {
            //search the collection of tab pages
            //for frmSearch froms
            //with tag of searchCrit
            //Crownwood.Magic.Controls.TabControl tctrl = m_frm.m_clsMain.tabControl1;


            IEnumerator ie = m_frm.m_clsMain.tabControl1.TabPages.GetEnumerator();

            while (ie.MoveNext())
            {
                Crownwood.Magic.Controls.TabPage c = (Crownwood.Magic.Controls.TabPage)ie.Current;

                ////if (c.Name.Equals(controlName))
                //if (c.Control.GetType() == typeof(frmSearch));
                //{
                //    //return (frmSearch)c;
                //    Debug.WriteLine(c.Control.ToString());
                //}

                                //if (c.Name.Equals(controlName))
                //if( c.Control.Tag != null)
                //if (c.Control.Tag.ToString() == searchCrit )
                //{
                //    return (frmSearch)c.Control;
                //    //Debug.WriteLine(c.Control.ToString());
                //}

                try
                {
                    frmSearch frm = (frmSearch)c.Control;
                    //Debug.WriteLine("frmtag" + frm.Tag.ToString());
                    if( frm.Tag != null)
                        if (frm.Tag.ToString() == searchCrit)
                        {
                            return frm;
                            //Debug.WriteLine(c.Control.ToString());
                        }

                }
                catch
                {
                }
            }

            return null;


    

            //return new frmSearch(null,5);
        }
        #endregion

        #region Menu handlers

        #endregion

        #region Custom Windows Form Designer generated code

        #endregion

        #region Events

        #endregion

        #region Properties



        public string SearchString
        {
            get { return XMLSearchString; }
            set { XMLSearchString = value; }
        }
	
        #endregion

    }
}