using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Data;
using System.Data.SqlServerCe;
using System.Net;
using System.Drawing;
using SinosysHardware.net.mappoint.staging;



namespace SinosysHardware.Business
{
    class Services
    {

        public string AppPath = @"\Program Files\HardwareDistributor.sdf";
        public string ConnectionString =@"Data Source=""\Program Files\HardwareDistributor.sdf"";Max Database Size=128;Default Lock Escalation =100;";
        public string InternetUrl = "http://pc-201001151348/MyHardware/sqlcesa30.dll";

        public string Publisher = "pc-201001151348";
        public string PublisherDatabase = "HardwareDistributor";
        public string Publication = "HardwarePublication";
        public string Subscriber = "HardwareSubscription";

    


        public  string MapPointUserName = "116972";
        public  string MapPointPassword = "P@ssw0rd";
        public  string MapPointFindServiceUrl ="http://findv3.staging.mappoint.net/Find-30/FindService.asmx";
        public  string MapPointRenderServiceUrl = "http://renderv3.staging.mappoint.net/Render-30/RenderService.asmx";
        public  string MapPointRouteServiceUrl = "http://routev3.staging.mappoint.net/Route-30/RouteService.asmx";



        public enum OrderState
        {
            Cancelled = 0,
            Placed = 1,
            Picked = 2,
            Loaded = 3,
            OutForDelivery = 4,
            Delivered = 5,
            All = 6
        }


        /// <summary>
        /// Tests to see if the SQL Server Everywhere database exists
        /// </summary>
        /// <returns></returns>
        public bool DatabaseExists()
        {
            ////Pass the application path plus the database name to the Exists method
            if (File.Exists(AppPath))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// Deletes a SQL Server Everywhere database
        /// </summary>
        public void DeleteDatabase()
        {
            File.Delete(AppPath);
        }

        /// <summary>
        /// Synchronize with a remote data source
        /// </summary>
        /// <param name="ex"></param>
        public void SyncWithDataSource()
        {
            SqlCeReplication repl = null;

            try
            {
                //Instantiate Replication Object
                repl = new SqlCeReplication();

                //Set Internet Properties
                repl.InternetUrl = InternetUrl;
         

                //Set Publisher Properties
                repl.Publisher = Publisher;
                repl.PublisherDatabase = PublisherDatabase;
                repl.Publication = Publication;

                //Set Security Property
                repl.PublisherSecurityMode = SecurityType.NTAuthentication;

                //Set Subscriber Properties
                repl.SubscriberConnectionString = ConnectionString;
                repl.Subscriber = Subscriber;

                //Check to see if Local Database Exists
                if (!File.Exists(AppPath))
                {
                    //If not, have the AddSubscription method create a new database
                    repl.AddSubscription(AddOption.CreateDatabase);
                }
                //Synchronize with SQL Server 2005
                repl.Synchronize();
            }
            finally
            {
                //Displose of Replication Object
                repl.Dispose();
            }
        }


        /// <summary>
        /// Instantiate MapPoint web services and call them as appropriate
        /// </summary>
        /// <param name="height"></param>
        /// <param name="width"></param>
        /// <param name="address"></param>
        /// <param name="city"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        public    Bitmap CallMapPoint(int height, int width, string address, string city, string state)
        {
            //Configure Credentials
            NetworkCredential _credentials = new NetworkCredential(MapPointUserName, MapPointPassword);

            //Configure FindServiceSoap
            FindServiceSoap _find = new FindServiceSoap();
            _find.Credentials = _credentials;
            _find.PreAuthenticate = true;
            _find.Url =MapPointFindServiceUrl;

            //Configure RenderServiceSoap
            RenderServiceSoap _render = new RenderServiceSoap();
            _render.Credentials = _credentials;
            _render.PreAuthenticate = true;
            _render.Url =MapPointRenderServiceUrl;

            //Configure RouteServiceSoap
            RouteServiceSoap _route = new RouteServiceSoap();
            _route.Credentials = _credentials;
            _route.PreAuthenticate = true;
            _route.Url =MapPointRouteServiceUrl;

            //Get the Lat and Long for the distribution center starting point
            Location _start = GetLatLong("1 Microsoft Way", "Redmond", "WA", _find);
            //Get the Lat and Long for the customer end point
             Location _end = GetLatLong(address, city, state, _find);
  
            //Get the route from the distribution center to the customer
            return GetRoute(_start, _end, _route, _render, height, width);
        }

  /// <summary>
        /// Get the Lat and Long based on an address
        /// </summary>
        /// <param name="address"></param>
        /// <param name="city"></param>
        /// <param name="state"></param>
        /// <param name="find"></param>
        /// <returns></returns>
        private  Location GetLatLong(string address, string city, string state, FindServiceSoap find)
        {
            //Create an address object
            Address _address = new Address();
            //Set the address object's properties
            _address.AddressLine = address;
            _address.PrimaryCity = city;
            _address.Subdivision = state;

            //Create a FindAddressSpecification object
            FindAddressSpecification _findAddressSpec = new FindAddressSpecification();
            //Set the FindAddressSpecification's properties
            _findAddressSpec.DataSourceName = "MapPoint.NA";
            _findAddressSpec.InputAddress = _address;

            //Retrieve address information
            FindResults _results = find.FindAddress(_findAddressSpec);

            //If address information exists
            if (_results.NumberFound == 0)
            {
                return null;
            }
            else
            {
                //Return the Location
                return _results.Results[0].FoundLocation;
            }
        }


        /// <summary>
        /// Get the route map that the driver needs to follow
        /// </summary>
        /// <param name="Start"></param>
        /// <param name="End"></param>
        /// <param name="route"></param>
        /// <param name="render"></param>
        /// <param name="height"></param>
        /// <param name="width"></param>
        /// <returns></returns>
        private  Bitmap GetRoute(Location Start, Location End, RouteServiceSoap route, RenderServiceSoap render, int height, int width)
        {
            //Creat a LatLong array 
            LatLong[] _latlongs = new LatLong[2];
            //Add the starting location
            _latlongs[0] = new LatLong();
            _latlongs[0] = Start.LatLong;
            //Add the ending location
            _latlongs[1] = new LatLong();
            _latlongs[1] = End.LatLong;

            //Create a MapOptions object
            MapOptions _options = new MapOptions();
            //Set the MapOptions' properties
            _options.Format = new ImageFormat();
            _options.Format.Height = height;
            _options.Format.Width = width;

            //Return a North American route based on the start and end lat and long
            Route _route = route.CalculateSimpleRoute(_latlongs, "MapPoint.NA", SegmentPreference.Quickest);
                        
            //Create a MapSpecification object
            MapSpecification _mapSpec = new MapSpecification();
            //Set the MapSpecification's properties
            _mapSpec.DataSourceName = "MapPoint.NA";
            _mapSpec.Options = _options;
            _mapSpec.Route = _route;
            
            //Call the MapPoint web service to return an array of maps
            MapImage[] _images = render.GetMap(_mapSpec);
            
            //Return the first map as a Bitmap object
            return new Bitmap(new MemoryStream(_images[0].MimeData.Bits));
        
        }
    }
}
