/// <summary>
        /// Successful FindMarker request callback function.
        /// </summary>
        /// <param name="response">FindMarker response.</param>
        public void FindMarkerCallbackOK(WSMarkerResponse response)
        {
            DateTime now    = DateTime.Now.ToUniversalTime();
            Marker   marker = new Marker(response.data.markerId,
                                         response.data.markerDescriptor,
                                         response.data.markerCustomData,
                                         DateTime.Parse(response.data.markerUpdateDate),
                                         now, now,
                                         DateTime.Parse(response.data.publishedFrom),
                                         DateTime.Parse(response.data.publishedTo),
                                         response.data.cacheEnabled,
                                         new MarkerDatabase(response.data.markerDatabase.id,
                                                            response.data.markerDatabase.code,
                                                            response.data.markerDatabase.customData,
                                                            response.data.markerDatabase.cloud,
                                                            now, now),
                                         response.data.arLogoEnabled);

            string appdatapath = RecognitionManager.GetAppDataPath();
            Thread thread      = new Thread(() => SaveLocalMarkerThread(marker, true, true, appdatapath, true));

            thread.Start();
            //SaveLocalMarker(marker, true, true);

            _findMarkerRequestRunning = false;
            Thread thread2 = new Thread(() => _dataProviderListener.FindMarkerCallback(marker));

            thread2.Start();
            //_dataProviderListener.FindMarkerCallback(marker);
        }
        public void LoadLocalDiscoverModelsOnStartUp(string[] discoverIds)
        {
            //save all local discover models
            string srcDiscoverPath = Application.streamingAssetsPath + "/markers3D/";

#if UNITY_EDITOR || UNITY_IOS
            if (!Directory.Exists(Application.streamingAssetsPath) || !Directory.Exists(srcDiscoverPath))
            {
                return;
            }
#endif
            string dstDiscoverPath = RecognitionManager.GetAppDataPath() + "markers3D/";

            if (!Directory.Exists(dstDiscoverPath))
            {
                Directory.CreateDirectory(dstDiscoverPath);
            }
            else
            {
                string[] discover_files = Directory.GetFiles(dstDiscoverPath);
                foreach (string ff in discover_files)
                {
                    File.Delete(ff);
                }
            }
#if UNITY_EDITOR || UNITY_IOS
            foreach (string dicoverId in discoverIds)
            {
                if (dicoverId == "")
                {
                    continue;
                }
                string filename        = Path.GetFileName(dicoverId + ".dat");
                string discoverSrcFile = srcDiscoverPath + filename;
                string discoverDstFile = dstDiscoverPath + filename;
                Debug.Log("Saving discover model " + discoverDstFile);
                File.WriteAllBytes(discoverDstFile, File.ReadAllBytes(discoverSrcFile));
            }
#else
            foreach (string dicoverId in discoverIds)
            {
                if (dicoverId == "")
                {
                    continue;
                }
                string filename = Path.GetFileName(dicoverId + ".dat");
                WWW    reader   = new WWW(srcDiscoverPath + filename);
                while (!reader.isDone)
                {
                }
                if (!String.IsNullOrEmpty(reader.error))
                {
                    continue;
                }
                string discoverDstFile = dstDiscoverPath + filename;
                Debug.Log("Saving discover model " + discoverDstFile);
                File.WriteAllBytes(discoverDstFile, reader.bytes);
            }
#endif
        }
        public static void SaveLocalMarkerFile(string markerId, byte[] markerDescriptor)
        {
            string markerFileName = markerId + ".dat";
            string markersFolder  = RecognitionManager.GetAppDataPath() + "markers";

            string markerFilePath = markersFolder + "/" + markerFileName;

            if (!Directory.Exists(markersFolder))
            {
                Directory.CreateDirectory(markersFolder);
            }

            if (!File.Exists(markerFilePath))
            {
                File.WriteAllBytes(markerFilePath, markerDescriptor);
            }
        }
        /// <summary>
        /// Instruct the local recognition service to save a marker.
        /// </summary>
        /// <param name="marker">Marker.</param>
        public void SaveLocalMarker(Marker marker, bool isRecognitionManagerRunning, bool replace, bool sync_after_save)
        {
            if (replace || !File.Exists(RecognitionManager.GetAppDataPath() + "markers/" + marker.markerId + ".dat"))
            {
                string dstMarkerPath = RecognitionManager.GetAppDataPath() + "markers/";
                if (!Directory.Exists(dstMarkerPath))
                {
                    Directory.CreateDirectory(dstMarkerPath);
                }

                if (isRecognitionManagerRunning)
                {
#if UNITY_EDITOR_OSX || (UNITY_IOS && !UNITY_EDITOR_WIN)
                    String sbId         = marker.markerId.ToString();
                    String sbDescriptor = marker.markerDescriptor;
#else
                    StringBuilder sbId         = new StringBuilder(marker.markerId.ToString());
                    StringBuilder sbDescriptor = new StringBuilder(marker.markerDescriptor);
#endif
                    Debug.Log("Loading marker PikkartARCore.SaveLocalMarker " + sbId);
                    PikkartARCore.SaveLocalMarker(sbId, sbDescriptor);
                }
                else
                {
                    SaveLocalMarkerFile(marker.markerId, Convert.FromBase64String(marker.markerDescriptor));
                }

                if (sync_after_save)
                {
                    PikkartARCore.SyncMarkersWithFolder();
                }
            }

            marker.markerDescriptor = null;
            _localRecognitionService.SaveMarker(marker, _localRecognitionService.GetMarker(marker.markerId) != null);
        }
        /// <summary>
        /// Deletes obsolete local data.
        /// </summary>
        /// <param name="cacheMilliseconds">Cache milliseconds.</param>
        /// <param name="isRecognitionManagerRunning">is recognition manager running.</param>
        public void DeleteObsoleteLocalData(bool deleteFilesNotInSqlite, bool isRecognitionManagerRunning)
        {
            List <string> markersFileNames = new List <string>();
            List <Marker> dbMarkers        = GetMarkersList();
            string        markersPath      = RecognitionManager.GetAppDataPath() + "markers";

            if (!Directory.Exists(markersPath))
            {
                Directory.CreateDirectory(markersPath);
            }

            if (dbMarkers.Count > 0)
            {
                foreach (Marker marker in dbMarkers)
                {
                    string   markerId       = marker.markerId;
                    string   markerFileName = markerId + ".dat";
                    DateTime?publishedTo    = marker.publishedTo;

                    markersFileNames.Add(markerFileName);

                    if (publishedTo == null)
                    {
                        continue;
                    }

                    if (publishedTo.Value.CompareTo(DateTime.Now.ToUniversalTime()) < 0)
                    {
                        if (isRecognitionManagerRunning)
                        {
#if UNITY_EDITOR_OSX || (UNITY_IOS && !UNITY_EDITOR_WIN)
                            PikkartARCore.DeleteLocalMarker(markerId, true);
#else
                            PikkartARCore.DeleteLocalMarker(new StringBuilder(markerId), true);
#endif
                        }
                        else
                        {
                            string markerFilePath = markersPath + "/" + markerFileName;
                            if (!Directory.Exists(markersPath))
                            {
                                Directory.CreateDirectory(markersPath);
                            }
                            if (File.Exists(markerFilePath))
                            {
                                File.Delete(markerFilePath);
                            }
                        }
                    }
                }
            }

            if (deleteFilesNotInSqlite)
            {
                var        info      = new DirectoryInfo(markersPath);
                FileInfo[] filesInfo = info.GetFiles();

                foreach (FileInfo fileInfo in filesInfo)
                {
                    if (fileInfo.Name.Contains(".dat") && !markersFileNames.Contains(fileInfo.Name))
                    {
                        fileInfo.Delete();
                    }
                }
            }

            dbu.DeleteObsoleteMarkers();
        }
        public void LoadLocalMarkersOnStartup(bool isRecognitionManagerRunning, string[] markerIds, string[] discoverIds)
        {
            LoadLocalDiscoverModelsOnStartUp(discoverIds);

            if (markerIds.Length < 1)
            {
                return;
            }

            string srcMarkerPath = Application.streamingAssetsPath + "/markers/";

#if UNITY_EDITOR || UNITY_IOS
            if (!Directory.Exists(Application.streamingAssetsPath) || !Directory.Exists(srcMarkerPath))
            {
                return;
            }
#endif
            string dstMarkerPath = RecognitionManager.GetAppDataPath() + "markers/";

            if (!Directory.Exists(dstMarkerPath))
            {
                Directory.CreateDirectory(dstMarkerPath);
            }
            else
            {
                string[] files = Directory.GetFiles(dstMarkerPath);
                foreach (string ff in files)
                {
                    File.Delete(ff);
                }
            }

            foreach (string markerId in markerIds)
            {
                Debug.Log("Loading marker " + markerId);
                if (markerId == "")
                {
                    continue;
                }

                string markerString = null;

#if UNITY_EDITOR || UNITY_IOS
                markerString = File.ReadAllText(srcMarkerPath + markerId + ".dat");
#else
                WWW reader = new WWW(srcMarkerPath + markerId + ".dat");
                while (!reader.isDone)
                {
                }
                if (!String.IsNullOrEmpty(reader.error))
                {
                    continue;
                }
                markerString = reader.text;
#endif
                if (markerString.Length > 0)
                {
                    Debug.Log("Loading marker save " + markerId);
                    WSMarkerResponse.WSMarker markerData = JsonUtilities.ToObject <WSMarkerResponse.WSMarker>(markerString);
                    DateTime now    = DateTime.Now.ToUniversalTime();
                    Marker   marker = new Marker(markerData.markerId,
                                                 markerData.markerDescriptor, markerData.markerCustomData,
                                                 DateTime.Parse(markerData.markerUpdateDate), now, now,
                                                 markerData.publishedFrom != null ? (DateTime?)DateTime.Parse(markerData.publishedFrom) : null,
                                                 markerData.publishedTo != null ? (DateTime?)DateTime.Parse(markerData.publishedTo) : null,
                                                 markerData.cacheEnabled,
                                                 new MarkerDatabase(markerData.markerDatabase.id, markerData.markerDatabase.code,
                                                                    markerData.markerDatabase.customData, markerData.markerDatabase.cloud, now, now),
                                                 markerData.arLogoEnabled);

                    SaveLocalMarker(marker, isRecognitionManagerRunning, true, false);
                }
            }
            PikkartARCore.SyncMarkersWithFolder();
        }