using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Web;
using Foresight.Data;
using Foresight.ServiceModel;
using IronIntel.Contractor.Machines;
using Foresight.Fleet.Services.Asset;
using Foresight.Fleet.Services.MapView;
using Foresight.Fleet.Services.JobSite;
using Foresight.Fleet.Services.Device;
using Foresight.Fleet.Services.User;
using System.Threading;
using DocumentFormat.OpenXml.Spreadsheet;

namespace IronIntel.Contractor.MapView
{
    public class AssetMapViewManagement : MachineManagement
    {
        /// <summary>
        /// 根据Contractorid获取机器列表
        /// </summary>
        /// <returns></returns>
        public static AssetMapViewPinItem[] GetAssets(string sessionid, string companyid, string useriid, string filtertext, int onroad, MachineAlertViewQueryParameter param, bool IncludeNoLocation, int attachment)
        {
            if (string.IsNullOrEmpty(companyid))
                companyid = SystemParams.CompanyID;

            MapViewAssetsQueryParam qp = new MapViewAssetsQueryParam();
            qp.FilterString = filtertext;
            qp.OnRoad = onroad;
            qp.IncludeNoLocation = IncludeNoLocation;
            if (param != null)
            {
                qp.ViewId = param.ViewID;
                qp.AlertViewQueryParam = param;
            }
            qp.Attachment = attachment;

            var client = FleetServiceClientHelper.CreateClient<MapViewQueryClient>(companyid, sessionid);
            AssetMapViewPinItem[] assets = client.GetAssets(companyid, useriid, qp);
            List<AssetMapViewPinItemClient> result = new List<AssetMapViewPinItemClient>();
            foreach (var a in assets)
            {
                AssetMapViewPinItemClient avi = new AssetMapViewPinItemClient();
                Helper.CloneProperty(avi, a);
                result.Add(avi);
            }
            return result.ToArray();
        }

        /// <summary>
        /// 获取Dealer站点下多个Contractor机器列表
        /// </summary>
        /// <returns></returns>
        public static AssetMapViewPinItem[] GetDealerAssets(string sessionid, string companyids, string useriid, string filtertext, int onroad, MachineAlertViewQueryParameter param, bool IncludeNoLocation, int attachment)
        {
            string[] cids = null;
            if (!string.IsNullOrEmpty(companyids))
                cids = companyids.Split(',');

            var contractors = SystemParams.GetContractors();
            if (cids == null || cids.Length == 0)
                cids = contractors.Select(c => c.ID).ToArray();

            if (cids == null || cids.Length == 0)
                return new AssetMapViewPinItem[0];

            int requestCount = 0;
            Exception lasterror = null;
            List<AssetMapViewPinItem> results = new List<AssetMapViewPinItem>();
            foreach (var cid in cids)
            {
                requestCount++;
                Thread th = new Thread((object state) =>
                {
                    try
                    {
                        var assets = GetAssets(sessionid, cid, useriid, filtertext, onroad, param, IncludeNoLocation, attachment);
                        lock (results)
                        {
                            foreach (var a in assets)
                            {
                                AssetMapViewPinItemClient asset = new AssetMapViewPinItemClient();
                                Helper.CloneProperty(asset, a);
                                var c = contractors.FirstOrDefault(t => t.ID.Equals(cid, StringComparison.OrdinalIgnoreCase));
                                if (c != null)
                                {
                                    asset.CompanyID = c.ID;
                                    asset.CompanyName = c.Name;
                                }
                                results.Add(asset);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        lasterror = ex;
                    }
                    requestCount--;
                });

                th.Start();
            }

            while (true)
            {
                Thread.Sleep(10);
                if (requestCount == 0)
                {
                    break;
                }
            }
            if (lasterror != null)
            {
                throw lasterror;
            }

            return results.ToArray();
        }

        /// <summary>
        /// 根据Contractorid获取机器基础信息列表
        /// </summary>
        /// <returns></returns>
        public static MapViewAssetItem[] GetAssetBasicInfos(string sessionid, string companyid, string useriid)
        {
            if (string.IsNullOrEmpty(companyid))
                companyid = SystemParams.CompanyID;

            var client = FleetServiceClientHelper.CreateClient<MapViewQueryClient>(companyid, sessionid);
            MapViewAssetItem[] assets = client.GetAvailableAssetItems(companyid, useriid);
            return assets.OrderBy(a => a.Id).ToArray();
        }

        /// <summary>
        /// 获取Dealer站点下多个Contractor机器基础信息列表
        /// </summary>
        /// <returns></returns>
        public static MapViewAssetItem[] GetDealerAssetBasicInfos(string sessionid, string companyids, string useriid)
        {
            string[] cids = null;
            if (!string.IsNullOrEmpty(companyids))
                cids = companyids.Split(',');

            var contractors = SystemParams.GetContractors();
            if (cids == null || cids.Length == 0)
                cids = contractors.Select(c => c.ID).ToArray();

            if (cids == null || cids.Length == 0)
                return new MapViewAssetItem[0];

            int requestCount = 0;
            Exception lasterror = null;
            List<MapViewAssetItem> results = new List<MapViewAssetItem>();
            foreach (var cid in cids)
            {
                requestCount++;
                Thread th = new Thread((object state) =>
                {
                    try
                    {
                        var assets = GetAssetBasicInfos(sessionid, cid, useriid);
                        lock (results)
                        {
                            results.AddRange(assets);
                        }
                    }
                    catch (Exception ex)
                    {
                        lasterror = ex;
                    }
                    requestCount--;
                });

                th.Start();
            }

            while (true)
            {
                Thread.Sleep(10);
                if (requestCount == 0)
                {
                    break;
                }
            }
            if (lasterror != null)
            {
                throw lasterror;
            }

            return results.OrderBy(a => a.Id).ToArray();
        }

        /// <summary>
        /// 根据机器ID获取机器基础信息列表
        /// </summary>
        public static MapViewAssetItem[] GetAssetItemsByAssets(string sessionid, string companyid, string useriid, long[] assetids)
        {
            if (string.IsNullOrEmpty(companyid))
                companyid = SystemParams.CompanyID;

            var client = FleetServiceClientHelper.CreateClient<MapViewQueryClient>(companyid, sessionid);
            MapViewAssetItem[] assets = client.GetAssetItemsByAssets(companyid, useriid, assetids);
            return assets.OrderBy(a => a.Id).ToArray();
        }


        /// <summary>
        /// 根据机器ID获取机器详细信息
        /// </summary>
        /// <returns></returns>
        public static AssetDetailViewItem GetAssetDetailItem(string sessionid, string companyid, long machineid, string datasource = null)
        {
            var client = FleetServiceClientHelper.CreateClient<AssetQueryClient>(companyid, sessionid);
            var locclient = FleetServiceClientHelper.CreateClient<AssetLocationQueryClient>(companyid, sessionid);
            var asset = client.GetAssetDetailInfo(companyid, machineid);
            var companyinfo = SystemParams.GetCustomerInfo(companyid);
            AssetDetailViewItem mi = new AssetDetailViewItem();
            if (companyinfo != null)
            {
                mi.CompanyID = companyinfo.ID;
                mi.CompanyName = companyinfo.Name;
            }
            mi.ID = asset.ID;
            mi.Name = asset.Name;
            mi.Name2 = asset.Name2;
            mi.VIN = asset.VIN;
            mi.MakeYear = asset.MakeYear;
            mi.Make = asset.MakeName;
            mi.Model = asset.ModelName;
            mi.AssetType = asset.TypeName;
            mi.GroupNames = asset.GroupNames;
            mi.IconUrl = asset.MapViewIconUrl;
            mi.AssetIconUrl = asset.AssetIconUrl;
            mi.Description = asset.Description;
            mi.DisplayName = asset.DisplayName;

            if (asset.CurrentHours != null)
            {
                mi.EngineHours = asset.CurrentHours.Corrected;
                mi.EngineHoursDate = asset.CurrentHours.AsofTimeLocal;
            }

            mi.Location = new LocationViewItem();
            var loc = asset.CurrentLocation;
            if (!string.IsNullOrWhiteSpace(datasource)
                && (loc == null || string.Compare(datasource, loc.DataSource, true) != 0))
            {
                AssetLocationInfo[] locs = locclient.GetAssetCurrentLocation(companyid, machineid);
                var tempLoc = locs.FirstOrDefault(l => string.Compare(datasource, l.DataSource, true) != 0);
                if (tempLoc != null)
                {
                    mi.Location.Latitude = tempLoc.Latitude;
                    mi.Location.Longitude = tempLoc.Longitude;
                    mi.Location.LocationTime = tempLoc.AsofTimeLocal;
                    mi.Location.Speed = tempLoc.Speed;
                    mi.Location.SpeedUnit = tempLoc.SpeedUnits;
                    mi.Location.PostedSpeed = tempLoc.PostedSpeedLimit;
                    mi.Location.PostedSpeedUnit = tempLoc.SpeedLimitUnits;
                    mi.Location.Street = tempLoc.Street;

                    //MapView页面 不会走此分支，所以暂时不用对DataSource/SubSource/EventType/MsgUID赋值
                }
            }
            else if (loc != null)
            {
                mi.Location.Latitude = loc.Latitude;
                mi.Location.Longitude = loc.Longitude;
                mi.Location.LocationTime = loc.AsofTimeLocal;
                mi.Location.Speed = loc.Speed;
                mi.Location.SpeedUnit = loc.SpeedUnits;
                mi.Location.PostedSpeed = loc.PostedSpeedLimit;
                mi.Location.PostedSpeedUnit = loc.SpeedLimitUnits;
                mi.Location.Street = loc.Street;

                //当前位置没有LogID,通过DataSource/SubSource/EventType/MsgUID 来进行RequestVideo
                mi.Location.DataSource = loc.DataSource;
                mi.Location.SubSource = loc.SubSource;
                mi.Location.EventType = loc.EventType;
                mi.Location.MsgUID = loc.MsgUID;
            }

            var assetDevices = client.GetPairedDevices(companyid, machineid);
            var device = assetDevices.FirstOrDefault(d => d.Source.Equals(Foresight.Fleet.Services.Device.DeviceInfo.DEVICESOURCE_SMARTWITNESS, StringComparison.OrdinalIgnoreCase)
            && d.Status == 1);
            mi.Location.FromSmartWitness = device == null ? false : true;//11342 通过机器当前是否绑定SmartWitness来判断

            if (asset.CurrentOdometer != null)
            {
                mi.Odometer = asset.CurrentOdometer.Corrected;
                mi.OdometerUOM = asset.CurrentOdometer.UOM;
            }

            return mi;
        }

        /// <summary>
        /// 根据Contractorid获取机器组列表
        /// </summary>
        /// <returns></returns>
        public static AssetGroupViewItem[] GetAssetGroups(string sessionid, string companyid, string useriid, string searchtext)
        {
            var client = FleetServiceClientHelper.CreateClient<MapViewQueryClient>(companyid, sessionid);
            AssetGroupInfo[] gs = client.GetAvailableAssetGroups(companyid, useriid, searchtext, false);

            List<AssetGroupViewItem> list = new List<AssetGroupViewItem>();
            foreach (var g in gs)
            {
                AssetGroupViewItem ag = new AssetGroupViewItem();
                ag.ID = g.Id;
                ag.Name = g.Name;
                //ag.Assets = g.Assets;
                list.Add(ag);
            }
            return list.ToArray();
        }

        /// <summary>
        /// 获取Dealer站点下多个Contractor机器组列表
        /// </summary>
        /// <returns></returns>
        public static AssetGroupViewItem[] GetDealerAssetGroups(string sessionid, string companyids, string useriid, string searchtext)
        {
            string[] cids = null;
            if (!string.IsNullOrEmpty(companyids))
                cids = companyids.Split(',');

            var contractors = SystemParams.GetContractors();
            if (cids == null || cids.Length == 0)
                cids = contractors.Select(c => c.ID).ToArray();

            if (cids == null || cids.Length == 0)
                return new AssetGroupViewItem[0];

            int requestCount = 0;
            Exception lasterror = null;
            List<AssetGroupViewItem> results = new List<AssetGroupViewItem>();
            foreach (var cid in cids)
            {
                requestCount++;
                Thread th = new Thread((object state) =>
                {
                    try
                    {
                        var ags = GetAssetGroups(sessionid, cid, useriid, searchtext);
                        lock (results)
                        {
                            foreach (var ag in ags)
                            {
                                var c = contractors.FirstOrDefault(t => t.ID.Equals(cid, StringComparison.OrdinalIgnoreCase));
                                if (c != null)
                                {
                                    ag.CompanyID = c.ID;
                                    ag.CompanyName = c.Name;
                                }
                            }
                            results.AddRange(ags);
                        }
                    }
                    catch (Exception ex)
                    {
                        lasterror = ex;
                    }
                    requestCount--;
                });

                th.Start();
            }

            while (true)
            {
                Thread.Sleep(10);
                if (requestCount == 0)
                {
                    break;
                }
            }
            if (lasterror != null)
            {
                throw lasterror;
            }

            return results.ToArray();
        }

        /// <summary>
        /// 根据Contractorid获取Jobsite列表
        /// </summary>
        /// <returns></returns>
        public static JobSiteViewItem[] GetJobsites(string sessionid, string companyid, string useriid, string searchtext)
        {
            if (string.IsNullOrEmpty(companyid))
                companyid = SystemParams.CompanyID;

            var client = FleetServiceClientHelper.CreateClient<MapViewQueryClient>(companyid, sessionid);
            MapViewJobSiteInfo[] jss = client.GetAvailableJobSites(companyid, useriid, searchtext, false);

            List<JobSiteViewItem> list = new List<JobSiteViewItem>();
            foreach (var js in jss)
            {
                JobSiteViewItem ajs = new JobSiteViewItem();
                ajs.ID = js.ID;
                ajs.Name = js.Name;
                ajs.Latitude = js.Latitude;
                ajs.Longitude = js.Longitude;
                ajs.Radius = js.Radius;
                ajs.Radius_UOM = js.RadiusUOM;
                if (js.StartDate != null)
                    ajs.StartDate = js.StartDate.Value;
                if (js.EndDate != null)
                    ajs.EndDate = js.EndDate.Value;
                if (js.ProjectedEndDate != null)
                    ajs.ProjectedEndDate = js.ProjectedEndDate.Value;

                //ajs.Assets = js.Assets;

                ajs.ColorString = js.Color;
                System.Drawing.Color color = System.Drawing.Color.Orange;
                try
                {
                    color = System.Drawing.ColorTranslator.FromHtml(js.Color);
                }
                catch
                {
                }
                ajs.Color = new IIColor() { Alpha = color.A, Red = color.R, Green = color.G, Blue = color.B };
                if (js.Polygon != null)
                {
                    List<PostionItem> temp = new List<PostionItem>();
                    foreach (var p in js.Polygon)
                    {
                        temp.Add(new PostionItem(p.Latitude, p.Longtitude));
                    }
                    ajs.Polygon = temp.ToArray();
                }
                ajs.Notes = js.Notes;
                ajs.Code = js.Code;
                ajs.RegionId = js.ReginId;
                ajs.Region = js.Region;
                ajs.Number = js.Number;
                ajs.Foreman = js.Foreman;
                ajs.Manager = js.Manager;
                ajs.Phone = js.Phone;
                ajs.Email = js.Email;
                ajs.Group = js.Group;
                ajs.Address1 = js.Address1;
                ajs.Address2 = js.Address2;
                ajs.City = js.City;
                ajs.State = js.State;
                ajs.Zip = js.Zip;
                ajs.County = js.County;
                ajs.BaseOnMachineID = js.BaseonMachineID;
                ajs.Types = new string[] { js.JobSiteTypes };
                list.Add(ajs);
            }
            return list.ToArray();
        }

        /// <summary>
        ///获取Dealer站点下多个Contractor Jobsite列表
        /// </summary>
        /// <returns></returns>
        public static JobSiteViewItem[] GetDealerJobsites(string sessionid, string companyids, string useriid, string searchtext)
        {
            string[] cids = null;
            if (!string.IsNullOrEmpty(companyids))
                cids = companyids.Split(',');

            var contractors = SystemParams.GetContractors();
            if (cids == null || cids.Length == 0)
                cids = contractors.Select(c => c.ID).ToArray();

            if (cids == null || cids.Length == 0)
                return new JobSiteViewItem[0];

            int requestCount = 0;
            Exception lasterror = null;
            List<JobSiteViewItem> results = new List<JobSiteViewItem>();
            foreach (var cid in cids)
            {
                requestCount++;
                Thread th = new Thread((object state) =>
                {
                    try
                    {
                        var jss = GetJobsites(sessionid, cid, useriid, searchtext);
                        lock (results)
                        {
                            foreach (var js in jss)
                            {
                                var c = contractors.FirstOrDefault(t => t.ID.Equals(cid, StringComparison.OrdinalIgnoreCase));
                                if (c != null)
                                {
                                    js.CompanyID = c.ID;
                                    js.CompanyName = c.Name;
                                }
                            }
                            results.AddRange(jss);
                        }
                    }
                    catch (Exception ex)
                    {
                        lasterror = ex;
                    }
                    requestCount--;
                });

                th.Start();
            }

            while (true)
            {
                Thread.Sleep(10);
                if (requestCount == 0)
                {
                    break;
                }
            }
            if (lasterror != null)
            {
                throw lasterror;
            }

            return results.ToArray();
        }

        /// <summary>
        /// 根据机器Id获取机器基本信息和位置历史记录
        /// </summary>
        /// <returns></returns>
        public static AssetLocationHistoryViewItem GetMachineLocationHistory(string sessionid, string machineid, DateTime startTime, DateTime endTime, string companyid, bool notShow00loc, string datasource)
        {
            if (string.IsNullOrEmpty(companyid))
                companyid = SystemParams.CompanyID;

            var client = FleetServiceClientHelper.CreateClient<AssetQueryClient>(companyid, sessionid);
            AssetBasicInfo asset = client.GetAssetBasicInfoByID(companyid, Convert.ToInt64(machineid));
            //AssetViewItem ai = new AssetViewItem();
            //Helper.CloneProperty(ai, asset);

            var assetDevices = client.GetPairedDevices(companyid, long.Parse(machineid));
            var device = assetDevices.FirstOrDefault(d => d.Source.Equals(Foresight.Fleet.Services.Device.DeviceInfo.DEVICESOURCE_SMARTWITNESS, StringComparison.OrdinalIgnoreCase)
            && d.Status == 1);

            var locclient = FleetServiceClientHelper.CreateClient<AssetLocationQueryClient>(companyid, sessionid);
            AssetLocationInfo[] assetLocs = locclient.GetAssetBasicLocationHistory(companyid, long.Parse(machineid), startTime, endTime, datasource, "", !notShow00loc);

            List<LocationViewItem> ls = new List<LocationViewItem>();
            foreach (AssetLocationInfo assetLoc in assetLocs)
            {
                LocationViewItem li = new LocationViewItem();
                li.LogId = assetLoc.LogId;
                li.Latitude = assetLoc.Latitude;
                li.Longitude = assetLoc.Longitude;
                li.LocationTime = assetLoc.AsofTimeLocal;

                //历史位置通过Logid进行RequestVideo，无需对DataSource/SubSource/EventType/MsgUID 赋值
                li.LogId = assetLoc.LogId;

                li.Speed = assetLoc.Speed;
                li.SpeedUnit = assetLoc.SpeedUnits;
                li.PostedSpeed = assetLoc.PostedSpeedLimit;
                li.PostedSpeedUnit = assetLoc.SpeedLimitUnits;
                li.Street = assetLoc.Street;
                li.HarshDringEvent = assetLoc.HarshDringEvent;
                li.SpeedingBehavior = assetLoc.SpeedingBehavior;
                li.IconURL = GenerateLocationIconUrl(assetLoc, asset.OnRoad);
                li.SmartWitnessVideoUrl = assetLoc.SmartWitnessVideoUrl;

                li.FromSmartWitness = device == null ? false : true;//11342 通过机器当前是否绑定SmartWitness来判断

                //ConvertSpeedUnitToMile(li);
                ls.Add(li);
            }
            AssetLocationHistoryViewItem al = new AssetLocationHistoryViewItem();
            al.Machine = asset;
            al.Locations = ls.ToArray();
            return al;
        }

        /// <summary>
        /// 根据位置信息生成位置图标Url
        /// </summary>
        /// <returns></returns>
        private static string GenerateLocationIconUrl(AssetLocationInfo loc, bool onRoad)
        {
            string path = SystemParams.MachineMovingIconUrl;
            const string PARAM = "?tp={0}&bkcolor={1}&heading={2}";
            int tp = (int)HarshDrivingEvents.HardAccelerationEvent;
            string color = "";
            if (onRoad)
            {
                switch (loc.HarshDringEvent)
                {
                    case HarshDrivingEvents.None:
                        break;
                    case HarshDrivingEvents.HardAccelerationEvent:
                        color = "#ff3f48cc";
                        break;
                    case HarshDrivingEvents.HardBrakeEvent:
                        color = "#ff00a8f3";
                        break;
                    case HarshDrivingEvents.HardTurnEvent:
                        color = "#fffff200";
                        break;
                }
                if (string.IsNullOrEmpty(color))
                {
                    if (loc.SpeedingBehavior == SpeedingBehaviors.MinorSpeeding)
                        color = "#ffff7f27";
                    else if (loc.SpeedingBehavior == SpeedingBehaviors.SevereSpeeding)
                        color = "#ffec1c24";
                }
            }
            if (string.IsNullOrEmpty(color))
            {
                if (loc.MoveStatus == AssetMoveStatus.InMotion)
                    color = "#ff228B22";
            }

            if (loc.Speed <= 0 && loc.MoveStatus == AssetMoveStatus.Unknown)
                loc.Heading = -1;

            if (string.IsNullOrEmpty(color))
            {
                if (loc.MoveStatus == AssetMoveStatus.StoppedOn)
                    return path + "?legend=StoppedOn";
                else if (loc.MoveStatus == AssetMoveStatus.StoppedOff)
                    return path + "?legend=StoppedOff";
                else if (loc.MoveStatus == AssetMoveStatus.ConnectivityRecovery)
                    return path + "?legend=CGAIN";
                else if (loc.MoveStatus == AssetMoveStatus.ConnectivityLose)
                    return path + "?legend=CLOSS";
            }
            color = HttpUtility.UrlEncode(color);
            path = path + string.Format(PARAM, tp, color, loc.Heading);

            return path;
        }

        /// <summary>
        /// 根据contractorid获取地图AlertView定义列表
        /// </summary>
        /// <returns></returns>
        public static MapAlertViewDefinitionItem[] GetMapAlertViews(string sessionid, string companyid, string selectedViewID)
        {
            if (string.IsNullOrWhiteSpace(companyid))
                companyid = SystemParams.CompanyID;

            var client = FleetServiceClientHelper.CreateClient<MapViewQueryClient>(companyid, sessionid);
            AlertViewMapItem[] views = client.GetAlertViewMapItems(companyid);

            AlertViewMapItem viewInfo = null;
            try
            {
                if (!string.IsNullOrWhiteSpace(selectedViewID))//获取View下使用的数据源信息
                    viewInfo = client.GetAlertViewMapItem(companyid, selectedViewID);
            }
            catch { }

            string path = SystemParams.MachineTypeMapViewIconUrl;
            List<MapAlertViewDefinitionItem> ls = new List<MapAlertViewDefinitionItem>();
            foreach (AlertViewMapItem ai in views)
            {
                MapAlertViewDefinitionItem mi = new MapAlertViewDefinitionItem();
                mi.ID = ai.ID;
                mi.Name = ai.Name;

                if (viewInfo != null && viewInfo.ID.Equals(mi.ID, StringComparison.OrdinalIgnoreCase))
                {
                    mi.Layers = new MapAlertLayerDefinitionItem[viewInfo.Layers.Count];
                    for (int i = 0; i < viewInfo.Layers.Count; i++)
                    {
                        var layer = viewInfo.Layers[i];
                        mi.Layers[i] = new MapAlertLayerDefinitionItem();
                        mi.Layers[i].ID = layer.LayerId;
                        mi.Layers[i].Title = layer.Title;
                        mi.Layers[i].LegendUrl = layer.LegendUrl;

                        if (layer.Pivots != null && layer.Pivots.Count > 0)
                            mi.Layers[i].Pivots = ConvertPivotsDefine(layer.Pivots);
                    }
                    //mi.Layers = mi.Layers.OrderBy((l) => l.AlertLayerType).ToArray();
                    mi.LookupDataSources = ConvertLookupData(viewInfo.LookupDataSources);
                }
                ls.Add(mi);
            }
            return ls.OrderBy((mal) => mal.Name).ToArray();
        }

        /// <summary>
        ///获取Dealer站点下多个Contractor地图AlertView定义列表
        /// </summary>
        /// <returns></returns>
        public static MapAlertViewDefinitionItem[] GetDealerMapAlertViews(string sessionid, string companyids, string selectedViewID)
        {
            string[] cids = null;
            if (!string.IsNullOrEmpty(companyids))
                cids = companyids.Split(',');

            var contractors = SystemParams.GetContractors();
            if (cids == null || cids.Length == 0)
                cids = contractors.Select(c => c.ID).ToArray();

            if (cids == null || cids.Length == 0)
                return new MapAlertViewDefinitionItem[0];

            int requestCount = 0;
            Exception lasterror = null;
            List<MapAlertViewDefinitionItem> results = new List<MapAlertViewDefinitionItem>();
            foreach (var cid in cids)
            {
                requestCount++;
                Thread th = new Thread((object state) =>
                {
                    try
                    {
                        var client = FleetServiceClientHelper.CreateClient<MapViewQueryClient>(cid, sessionid);
                        AlertViewMapItem[] views = client.GetAlertViewMapItems(cid);

                        AlertViewMapItem viewInfo = null;
                        try
                        {
                            if (!string.IsNullOrWhiteSpace(selectedViewID))//获取View下使用的数据源信息
                                viewInfo = client.GetAlertViewMapItem(cid, selectedViewID);
                        }
                        catch { }

                        string path = SystemParams.MachineTypeMapViewIconUrl;
                        lock (results)
                        {
                            foreach (AlertViewMapItem ai in views)
                            {
                                MapAlertViewDefinitionItem mi = results.FirstOrDefault(r => r.ID.Equals(ai.ID, StringComparison.OrdinalIgnoreCase));
                                if (mi == null)
                                {
                                    mi = new MapAlertViewDefinitionItem();
                                    mi.ID = ai.ID;
                                    mi.Name = ai.Name;
                                    results.Add(mi);
                                }

                                if (viewInfo != null && viewInfo.ID.Equals(mi.ID, StringComparison.OrdinalIgnoreCase))
                                {
                                    mi.Layers = new MapAlertLayerDefinitionItem[viewInfo.Layers.Count];
                                    for (int i = 0; i < viewInfo.Layers.Count; i++)
                                    {
                                        var layer = viewInfo.Layers[i];
                                        mi.Layers[i] = new MapAlertLayerDefinitionItem();
                                        mi.Layers[i].ID = layer.LayerId;
                                        mi.Layers[i].Title = layer.Title;
                                        mi.Layers[i].LegendUrl = layer.LegendUrl;

                                        if (layer.Pivots != null && layer.Pivots.Count > 0)
                                            mi.Layers[i].Pivots = ConvertPivotsDefine(layer.Pivots);
                                    }
                                    //mi.Layers = mi.Layers.OrderBy((l) => l.AlertLayerType).ToArray();
                                    var lookupData = ConvertLookupData(viewInfo.LookupDataSources);
                                    mi.LookupDataSources.AddRange(lookupData);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        lasterror = ex;
                    }
                    requestCount--;
                });

                th.Start();
            }

            while (true)
            {
                Thread.Sleep(10);
                if (requestCount == 0)
                {
                    break;
                }
            }
            if (lasterror != null)
            {
                throw lasterror;
            }

            return results.OrderBy(r => r.Name).ToArray();
        }

        private static List<LookupDataSourceDataItem> ConvertLookupData(List<LookupDataSourceData> data)
        {
            List<LookupDataSourceDataItem> result = new List<LookupDataSourceDataItem>();
            if (data != null)
            {
                foreach (LookupDataSourceData d in data)
                {
                    LookupDataSourceDataItem item = new LookupDataSourceDataItem();
                    item.ID = d.ID;
                    item.Name = d.Name;
                    item.Items.AddRange(d.Items);
                    result.Add(item);
                }
            }
            return result;
        }

        private static AlertLayerPivotViewItem[] ConvertPivotsDefine(List<AlertLayerPivot> paramerters)
        {
            List<AlertLayerPivotViewItem> list = new List<AlertLayerPivotViewItem>();
            foreach (AlertLayerPivot pd in paramerters)
            {
                AlertLayerPivotViewItem pi = new AlertLayerPivotViewItem();
                Helper.CloneProperty(pi, pd);
                if (pi.DataType == DataTypes.Datetime)
                {
                    try
                    {
                        pi.DefaultValue = DateTime.Parse(pi.DefaultValue).ToString("M/d/yyyy");
                    }
                    catch
                    {
                    }
                }
                list.Add(pi);
            }

            return list.ToArray();
        }

        /// <summary>
        /// 根据Contractorid获取Shape列表
        /// </summary>
        /// <returns></returns>
        public static ShapeFileItem[] GetShapes(string sessionid, string companyid, string filtertext)
        {
            if (string.IsNullOrEmpty(companyid))
                companyid = SystemParams.CompanyID;

            ShapeFileInfo[] files = FleetServiceClientHelper.CreateClient<ShapeFileProvider>(companyid, sessionid).GetShapeFileInfos(companyid, filtertext);
            if (files == null || files.Length == 0)
                return new ShapeFileItem[0];

            List<ShapeFileItem> list = new List<ShapeFileItem>();
            foreach (ShapeFileInfo fi in files)
            {
                ShapeFileItem item = new ShapeFileItem();
                Helper.CloneProperty(item, fi);
                list.Add(item);
            }
            return list.OrderBy(m => m.Name).ToArray();
        }

        /// <summary>
        /// 获取Dealer站点下多个Contractor机器列表
        /// </summary>
        /// <returns></returns>
        public static ShapeFileItem[] GetDealerShapes(string sessionid, string companyids, string filtertext)
        {
            string[] cids = null;
            if (!string.IsNullOrEmpty(companyids))
                cids = companyids.Split(',');

            var contractors = SystemParams.GetContractors();
            if (cids == null || cids.Length == 0)
                cids = contractors.Select(c => c.ID).ToArray();

            if (cids == null || cids.Length == 0)
                return new ShapeFileItem[0];

            int requestCount = 0;
            Exception lasterror = null;
            List<ShapeFileItem> results = new List<ShapeFileItem>();
            foreach (var cid in cids)
            {
                requestCount++;
                Thread th = new Thread((object state) =>
                {
                    try
                    {
                        ShapeFileInfo[] files = FleetServiceClientHelper.CreateClient<ShapeFileProvider>(cid, sessionid).GetShapeFileInfos(cid, filtertext);
                        lock (results)
                        {
                            foreach (ShapeFileInfo fi in files)
                            {
                                ShapeFileItem item = new ShapeFileItem();
                                Helper.CloneProperty(item, fi);
                                var c = contractors.FirstOrDefault(t => t.ID.Equals(cid, StringComparison.OrdinalIgnoreCase));
                                if (c != null)
                                {
                                    item.CompanyID = c.ID;
                                    item.CompanyName = c.Name;
                                }
                                results.Add(item);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        lasterror = ex;
                    }
                    requestCount--;
                });

                th.Start();
            }

            while (true)
            {
                Thread.Sleep(10);
                if (requestCount == 0)
                {
                    break;
                }
            }
            if (lasterror != null)
            {
                throw lasterror;
            }

            return results.ToArray();
        }


        /// <summary>
        /// 根据Contractorid获取Location列表
        /// </summary>
        /// <returns></returns>
        public static CompanyLocationViewItem[] GetLocations(string sessionid, string companyid)
        {
            if (string.IsNullOrEmpty(companyid))
                companyid = SystemParams.CompanyID;

            var client = FleetServiceClientHelper.CreateClient<MapViewQueryClient>(companyid, sessionid);
            CustomerLocation[] locs = client.GetCompanyLocations(companyid);
            List<CompanyLocationViewItem> temps = new List<CompanyLocationViewItem>();
            foreach (var loc in locs)
            {
                CompanyLocationViewItem l = new CompanyLocationViewItem();
                l.ID = loc.ID;
                l.Latitude = loc.Latitude;
                l.Longitude = loc.Longitude;
                l.LocationName = loc.Name;
                l.Notes = loc.Notes;
                l.IconUrl = loc.IconUrl;
                temps.Add(l);
            }
            return temps.ToArray();
        }

        /// <summary>
        /// 获取Dealer站点下多个Contractor机器列表
        /// </summary>
        /// <returns></returns>
        public static CompanyLocationViewItem[] GetDealerLocations(string sessionid, string companyids)
        {
            string[] cids = null;
            if (!string.IsNullOrEmpty(companyids))
                cids = companyids.Split(',');

            var contractors = SystemParams.GetContractors();
            if (cids == null || cids.Length == 0)
                cids = contractors.Select(c => c.ID).ToArray();

            if (cids == null || cids.Length == 0)
                return new CompanyLocationViewItem[0];

            int requestCount = 0;
            Exception lasterror = null;
            List<CompanyLocationViewItem> results = new List<CompanyLocationViewItem>();
            foreach (var cid in cids)
            {
                requestCount++;
                Thread th = new Thread((object state) =>
                {
                    try
                    {
                        var client = FleetServiceClientHelper.CreateClient<MapViewQueryClient>(cid, sessionid);
                        CustomerLocation[] locs = client.GetCompanyLocations(cid);
                        lock (results)
                        {
                            foreach (var loc in locs)
                            {
                                CompanyLocationViewItem l = new CompanyLocationViewItem();
                                l.ID = loc.ID;
                                l.Latitude = loc.Latitude;
                                l.Longitude = loc.Longitude;
                                l.LocationName = loc.Name;
                                l.Notes = loc.Notes;
                                l.IconUrl = loc.IconUrl;
                                results.Add(l);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        lasterror = ex;
                    }
                    requestCount--;
                });

                th.Start();
            }

            while (true)
            {
                Thread.Sleep(10);
                if (requestCount == 0)
                {
                    break;
                }
            }
            if (lasterror != null)
            {
                throw lasterror;
            }

            return results.ToArray();
        }
    }
}
