using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using OSGeo.MapGuide.Viewer;
using OSGeo.MapGuide;

namespace SampleExtension
{
    public partial class WorkingWithFeatureData : MgControlView
    {
        private IMapViewer _viewer;

        public WorkingWithFeatureData(IMapViewer viewer)
        {
            InitializeComponent();
            _viewer = viewer;
            this.Title = "Working With Feature Data";
            _viewer.SelectionChanged += OnSelectionChanged;
            CheckSelectionState();
        }

        protected override void SubCleanup()
        {
            //When subscribing to events, be a responsible user and 
            //unsubscribe on cleanup
            _viewer.SelectionChanged -= OnSelectionChanged;
        }

        void OnSelectionChanged(object sender, EventArgs e)
        {
            CheckSelectionState();
        }

        void CheckSelectionState()
        {
            MgSelectionBase selection = _viewer.GetSelection();
            MgReadOnlyLayerCollection layers = selection.GetLayers();
            btnListSelected.Enabled = (layers != null);
        }

        private void btnZoomToDistrict1_Click(object sender, EventArgs e)
        {
            _viewer.ZoomToView(-87.726134, 43.770338, 8000, true);
        }

        private void btnQueryDistrict1_Click(object sender, EventArgs e)
        {
            MgMapBase map = _viewer.GetMap();
            MgLayerCollection layers = map.GetLayers();
            MgLayerBase districts = layers.GetItem("Districts");
            MgLayerBase parcels = layers.GetItem("Parcels");

            //Query the geometry of district 1
            MgFeatureQueryOptions districtQuery = new MgFeatureQueryOptions();
            districtQuery.SetFilter("Autogenerated_SDF_ID = 1");

            MgFeatureReader reader = districts.SelectFeatures(districtQuery);
            MgGeometry districtGeom = null;
            MgAgfReaderWriter agfRw = new MgAgfReaderWriter();
            try
            {
                reader.ReadNext();
                MgByteReader geomAgf = reader.GetGeometry(districts.GetFeatureGeometryName());
                districtGeom = agfRw.Read(geomAgf);
            }
            finally
            {
                reader.Close();
            }

            //Now use this geometry as the basis of our 2nd query

            MgFeatureQueryOptions parcelQuery = new MgFeatureQueryOptions();
            parcelQuery.SetFilter("RNAME LIKE 'SCHMITT%'");
            parcelQuery.SetSpatialFilter(parcels.GetFeatureGeometryName(), districtGeom, MgFeatureSpatialOperations.Inside);

            //Select the features
            reader = parcels.SelectFeatures(parcelQuery);
            List<string> results = new List<string>();
            try
            {
                while (reader.ReadNext())
                {
                    if (!reader.IsNull("RPROPAD"))
                        results.Add(reader.GetString("RPROPAD"));
                }
            }
            finally
            {
                reader.Close();
            }

            new ParcelQueryResultWindow(results).ShowDialog();
        }

        private void btnSelectDistrict1_Click(object sender, EventArgs e)
        {
            MgMapBase map = _viewer.GetMap();
            MgLayerCollection layers = map.GetLayers();
            MgLayerBase districts = layers.GetItem("Districts");
            MgLayerBase parcels = layers.GetItem("Parcels");

            //Query the geometry of district 1
            MgFeatureQueryOptions districtQuery = new MgFeatureQueryOptions();
            districtQuery.SetFilter("Autogenerated_SDF_ID = 1");

            MgFeatureReader reader = districts.SelectFeatures(districtQuery);
            MgGeometry districtGeom = null;
            MgAgfReaderWriter agfRw = new MgAgfReaderWriter();
            try
            {
                reader.ReadNext();
                MgByteReader geomAgf = reader.GetGeometry(districts.GetFeatureGeometryName());
                districtGeom = agfRw.Read(geomAgf);
            }
            finally
            {
                reader.Close();
            }

            //Now use this geometry as the basis of our 2nd query

            MgFeatureQueryOptions parcelQuery = new MgFeatureQueryOptions();
            parcelQuery.SetFilter("RNAME LIKE 'SCHMITT%'");
            parcelQuery.SetSpatialFilter(parcels.GetFeatureGeometryName(), districtGeom, MgFeatureSpatialOperations.Inside);

            //Select the features
            reader = parcels.SelectFeatures(parcelQuery);

            MgSelectionBase selection = _viewer.GetSelection();
            try
            {
                selection.FromXml(""); //Clear existing selection data
                selection.AddFeatures(parcels, reader, 0);
            }
            finally
            {
                reader.Close();
            }

            //Because we manipulated the active selection outside the viewer
            //We need to call UpdateSelection() to instruct the viewer to
            //re-render the active selection. The "true" parameter instructs
            //the viewer to raise the SelectionChanged event as well, so that
            //subscribers like the Property Pane get updated as well.
            _viewer.UpdateSelection(true);
            _viewer.RefreshMap();
        }

        private void btnListSelected_Click(object sender, EventArgs e)
        {
            // There's two ways to process a selection
            // 
            // 1. Iterate through the layers of a MgSelectionSet and process
            // the feature reader for each layer
            //
            // 2. Use an MgSelectionSet helper class
            //
            // This example shows the 2nd way, which is the simpler one
            MgSelectionBase selection = _viewer.GetSelection();
            MgMapViewerProvider provider = _viewer.GetProvider();
            MgSelectionSet sset = new MgSelectionSet(selection);

            new SelectedFeaturesWindow(sset).ShowDialog();
        }
    }
}