using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using Blog.SoeExample.Model;

namespace Blog.SoeExample.Repository
{
    public class ExampleRepository : IExampleRepository
    {
        private IQueryFilter queryFilter;

        // constructor - injects queryFilter dependency
        public ExampleRepository(IQueryFilter queryFilter)
        {
            this.queryFilter = queryFilter;
        }

        // workspace dependency
        public IWorkspace Workspace { get; set; }

        // select parcels with matching land use
        public IList<Parcel> SelectParcelsWithLandUse(string landUse)
        {
            // validate the landuse to prevent SQL injection
            var regex = new Regex("^[A-Z0-9]$");

            if (!regex.IsMatch(landUse))
            {
                throw new ArgumentException("The Land Use is invalid");
            }

            // cast to a feature workspace to get the desired feature class
            var featureWorkspace = (IFeatureWorkspace)this.Workspace;
            var featureClass = featureWorkspace.OpenFeatureClass("Geodatabase.DBO.ExampleLandUseParcels");

            // select features using the land user code
            this.queryFilter.WhereClause = "LandUseCode = '" + landUse + "'";
            var featureCursor = featureClass.Search(this.queryFilter, false);

            // create a list of Parcel models from the result features
            var parcels = new List<Parcel>();

            IFeature feature;

            // loop through the parcels and add to the collection of models
            while ((feature = featureCursor.NextFeature()) != null)
            {
                var parcel = new Parcel();

                // set shape and description value
                parcel.Geometry = feature.Shape;
                parcel.Description = (string)feature.get_Value(featureClass.FindField("Description"));

                parcels.Add(parcel);
            }

            Marshal.ReleaseComObject(featureCursor);
            Marshal.ReleaseComObject(featureClass);

            return parcels;
        }
    }
}