/// <summary>
 /// called when downloads are enabled
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void downloadCloud_Checked_1(object sender, RoutedEventArgs e)
 {
     if (XmlDataLayer.GetConfigEntry("sync_online") == "enabled")
     {
         abortDownloadDriveThread();
         XmlDataLayer.SetConfigEntry("download_cloud", "enabled");
         Thread newThread = new Thread(() => GoogleDriveSync.UploadDownloadNewFiles());
         newThread.Start();
     }
 }
        /// <summary>
        /// Main function which authenticates and creates threads for uploads and downloads if they are enabled
        /// </summary>
        /// <param name="createThreads"></param>
        public static void UploadDownloadNewFiles(bool createThreads = true)
        {
            if (authProgress)
            {
                return;
            }
            authProgress = true;
            DriveService service = getDriveService();

            if (service == null)
            {
                Thread.Sleep(5 * 60 * 1000);
                UploadDownloadNewFiles();
                return;
            }
            File file2 = null, tempFile = null;

            try
            {
                About  ab     = service.About.Get().Fetch();
                string rootId = ab.RootFolderId;

                file2    = makeDirectoryIfNotExists(service, "PCTrack", rootId);
                tempFile = makeDirectoryIfNotExists(service, "Temp", file2.Id);
            }
            catch (Exception)
            {
                XmlDataLayer.SetConfigEntry("authentication", "not_done");
                Thread.Sleep(5 * 60 * 1000);
                UploadDownloadNewFiles();
                return;
            }
            XmlDataLayer.SetConfigEntry("authentication", "done");

            if (createThreads)
            {
                try
                {
                    if (XmlDataLayer.GetConfigEntry("download_cloud") == "enabled")
                    {
                        downloadThread = new Thread(() => DownloadTempFiles(service, tempFile.Id));
                        downloadThread.Start();
                    }
                    if (XmlDataLayer.GetConfigEntry("upload_cloud") == "enabled")
                    {
                        uploadThread = new Thread(() => UploadTempFiles(service, tempFile.Id));
                        uploadThread.Start();
                    }
                }
                catch (Exception)
                {
                }
            }
            authProgress = false;
        }
        /// <summary>
        /// thread to upload temp files
        /// </summary>
        /// <param name="service"></param>
        /// <param name="folderId"></param>
        private static void UploadTempFiles(DriveService service, string folderId)
        {
            while (true)
            {
                string tempFolder = XmlDataLayer.GetUserApplicationDirectory() + "\\Temp";
                foreach (string f in System.IO.Directory.EnumerateFiles(tempFolder))
                {
                    try
                    {
                        string fileName = f.Split('\\')[f.Split('\\').Length - 1];
                        if (fileName == XmlDataLayer.GetCurrentTempFileName() || XmlDataLayer.GetUploadEntry(fileName) == true)
                        {
                            continue;
                        }
                        File body = new File();
                        body.Title       = fileName;
                        body.Description = "PCTrack_id " + XmlDataLayer.GetConfigEntry("pc_id");
                        body.MimeType    = "text/plain";
                        body.Parents     = new List <ParentReference>()
                        {
                            new ParentReference()
                            {
                                Id = folderId
                            }
                        };
                        byte[] byteArray = System.IO.File.ReadAllBytes(f);
                        System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);

                        FilesResource.InsertMediaUpload request = service.Files.Insert(body, stream, "text/plain");
                        request.Upload();

                        File file = request.ResponseBody;
                        if (file != null)
                        {
                            XmlDataLayer.SetUploadEntry(fileName);
                        }
                    }
                    catch (Exception)
                    {
                        UploadDownloadNewFiles(false);
                    }
                }
                Thread.Sleep(5 * 60 * 1000);
            }
        }
        /// <summary>
        /// gets authorization from google drive
        /// </summary>
        /// <param name="arg"></param>
        /// <returns></returns>
        private static IAuthorizationState GetAuthorization(NativeApplicationClient arg)
        {
            if (XmlDataLayer.GetConfigEntry("authentication") == "done" &&
                System.IO.File.Exists(XmlDataLayer.GetUserApplicationDirectory() + "\\credentials"))
            {
                TaskCompletionSource <SelfAuthorizationState> tcs = new TaskCompletionSource <SelfAuthorizationState>();


                string filePath = XmlDataLayer.GetUserApplicationDirectory() + "\\credentials";

                var obj = System.IO.File.ReadAllText(filePath);
                tcs.SetResult(NewtonsoftJsonSerializer.Instance.Deserialize <SelfAuthorizationState>(obj));

                SelfAuthorizationState k = tcs.Task.Result;

                return(k);
            }
            else
            {
                // Get the auth URL:
                IAuthorizationState state = new AuthorizationState(new[] { DriveService.Scopes.Drive.GetStringValue() });
                state.Callback = new Uri(NativeApplicationClient.OutOfBandCallbackUrl);
                Uri authUri = arg.RequestUserAuthorization(state);

                // Request authorization from the user (by opening a browser window):

                Process.Start(authUri.ToString());

                Thread response = new Thread(GetResponse);
                response.SetApartmentState(ApartmentState.STA);
                response.IsBackground = true;
                response.Start();
                while (verificationEntered != true)
                {
                    Thread.Sleep(200);
                }
                string authCode = verificationString;

                // Retrieve the access token by using the authorization code:
                IAuthorizationState s = arg.ProcessUserAuthorization(authCode, state);
                var serialized        = NewtonsoftJsonSerializer.Instance.Serialize(s);
                System.IO.File.WriteAllText(XmlDataLayer.GetUserApplicationDirectory() + "\\credentials", serialized);
                return(s);
            }
        }
        /// <summary>
        /// called when online sync is enabled
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MenuItem_Checked_1(object sender, RoutedEventArgs e)
        {
            MenuItem menuItem = sender as MenuItem;

            XmlDataLayer.SetConfigEntry("sync_online", "enabled");
            string pcId = XmlDataLayer.GetConfigEntry("pc_id");

            if (pcId == null)
            {
                Random rnd = new Random();
                int    id  = rnd.Next(0, 1000000);
                XmlDataLayer.SetConfigEntry("pc_id", id.ToString());
            }
            uploadCloud.IsEnabled   = true;
            downloadCloud.IsEnabled = true;
            if (XmlDataLayer.GetConfigEntry("upload_cloud") == "enabled")
            {
                uploadCloud.IsChecked = true;
            }
            else
            {
                uploadCloud.IsChecked = false;
            }
            if (XmlDataLayer.GetConfigEntry("download_cloud") == "enabled")
            {
                downloadCloud.IsChecked = true;
            }
            else
            {
                downloadCloud.IsChecked = false;
            }
            Thread newThread = new Thread(() => GoogleDriveSync.UploadDownloadNewFiles());

            newThread.Start();
            MenuItem item = sender as MenuItem;
            bool     x    = item.IsChecked;
        }
        /// <summary>
        /// mainWindow constructor
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();

            bool isFirstTime = IsFirstTime();

            if (isFirstTime)
            {
                WindowState = System.Windows.WindowState.Normal;
                var dialog = new System.Windows.Forms.FolderBrowserDialog();
                dialog.Description = "Choose folder where application data wil be saved.";
                string folderPath = createFolder("C:\\users\\" + Environment.UserName + "\\Documents\\PCTrack");
                dialog.SelectedPath = folderPath;
                //dialog.RootFolder = Environment.SpecialFolder.MyDocuments;
                System.Windows.Forms.DialogResult result = dialog.ShowDialog();
                string res = dialog.SelectedPath;
                if (res.ToLower() != folderPath.ToLower())
                {
                    Directory.Delete(folderPath);
                }
                RegistryKey key;
                key = Registry.CurrentUser.OpenSubKey("Software", true).OpenSubKey("PCTrack", true);
                key.SetValue("Path", res);
            }

            List <KeyValuePair <string, double> > valueList = new List <KeyValuePair <string, double> >();

            valueList.Add(new KeyValuePair <string, double>("A", 0));
            valueList.Add(new KeyValuePair <string, double>("B", 0));

            ProcessStatGraph.DataContext = valueList;
            laptopStatGraph.DataContext  = valueList;

            this.Height             = SystemParameters.MaximizedPrimaryScreenHeight;
            this.Width              = SystemParameters.MaximizedPrimaryScreenWidth;
            pcPanel.Width           = SystemParameters.MaximizedPrimaryScreenWidth / 2.23;
            processPanel.Width      = SystemParameters.MaximizedPrimaryScreenWidth / 2.23;
            ProcessStatGraph.Width  = SystemParameters.MaximizedPrimaryScreenWidth / 2.23;
            laptopStatGraph.Width   = SystemParameters.MaximizedPrimaryScreenWidth / 2.23;
            ProcessStatGraph.Height = SystemParameters.MaximizedPrimaryScreenHeight / 2.8;
            laptopStatGraph.Height  = SystemParameters.MaximizedPrimaryScreenHeight / 2.8;
            this.Title              = "PCTrack";
            if (getPPresence() == "yes")
            {
                passwordItem.IsChecked = true;
            }
            else
            {
                passwordItem.IsChecked = false;
                startup = false;
            }
            if (XmlDataLayer.GetConfigEntry("sync_online") == "enabled")
            {
                syncToggle.IsChecked  = true;
                uploadCloud.IsEnabled = true;
                if (XmlDataLayer.GetConfigEntry("upload_cloud") == "enabled")
                {
                    uploadCloud.IsChecked = true;
                }
                downloadCloud.IsEnabled = true;
                if (XmlDataLayer.GetConfigEntry("download_cloud") == "enabled")
                {
                    downloadCloud.IsChecked = true;
                }
            }
            else
            {
                syncToggle.IsChecked = false;
            }
            if (XmlDataLayer.GetConfigEntry("upload_cloud") == "enabled")
            {
                uploadCloud.IsChecked = true;
            }
            if (XmlDataLayer.GetConfigEntry("download_cloud") == "enabled")
            {
                downloadCloud.IsChecked = true;
            }
            m_notifyIcon = new System.Windows.Forms.NotifyIcon();


            System.Windows.Forms.ContextMenu trayMenu = new System.Windows.Forms.ContextMenu();
            System.Windows.Forms.MenuItem    exit     = new System.Windows.Forms.MenuItem();
            exit.Text    = "exit";
            exit.Visible = true;
            exit.Click  += exit_Click;
            System.Windows.Forms.MenuItem pause = new System.Windows.Forms.MenuItem();
            pause.Text    = "pause";
            pause.Visible = true;
            pause.Click  += pause_Click;
            //exit.Click += exit_Click;
            trayMenu.MenuItems.Add(pause);
            trayMenu.MenuItems.Add(exit);
            m_notifyIcon.ContextMenu = trayMenu;

            //m_notifyIcon.BalloonTipText = "The app has been minimised. Click the tray icon to show.";
            m_notifyIcon.BalloonTipText  = null;
            m_notifyIcon.BalloonTipTitle = "PCTrack";
            m_notifyIcon.Text            = "PCTrack";
            string s = System.IO.Path.GetFullPath("systray.ico");

            m_notifyIcon.Icon         = new System.Drawing.Icon(s);
            m_notifyIcon.DoubleClick += new EventHandler(m_notifyIcon_DoubleClick);

            Uri iconUri = new Uri(s, UriKind.RelativeOrAbsolute);

            this.Icon = BitmapFrame.Create(iconUri);

            ContextMenu windowMenu = new ContextMenu();
            MenuItem    syncEntry  = new MenuItem();

            syncEntry.Header = "WPF";
            //syncEntry.Tag = new List<string> { date.ToString("yyyy-MM-dd"), start, end, process.Name };
            //syncEntry.Click += deleteProcessEntry_Click;
            windowMenu.Items.Add(syncEntry);
            this.ContextMenu = windowMenu;

            MainManager.SpawnProcesses();
            Thread refreshUserInterface = new Thread(refreshUI);

            refreshUserInterface.Start();

            WindowState = System.Windows.WindowState.Minimized;
            Hide();
            CheckTrayIcon();
        }
        /// <summary>
        /// thread to dowload temp files
        /// </summary>
        /// <param name="service"></param>
        /// <param name="parentId"></param>
        private static void DownloadTempFiles(DriveService service, string parentId)
        {
            while (true)
            {
                ChildrenResource.ListRequest request = service.Children.List(parentId);
                File file = null;
                do
                {
                    try
                    {
                        ChildList children = request.Fetch();

                        foreach (ChildReference child in children.Items)
                        {
                            //Console.WriteLine("File Id: " + child.Id);
                            file = service.Files.Get(child.Id).Fetch();
                            string title = file.Title.Replace(":", "_");
                            string id    = file.Description.Split(' ')[1];
                            if (XmlDataLayer.CheckIfTempExists(title) == true || XmlDataLayer.GetDownloadEntry(title) == true || id == XmlDataLayer.GetConfigEntry("pc_id"))
                            {
                                continue;
                            }
                            try
                            {
                                System.IO.Stream tfile = DownloadFile(createAuthenticator(), file);
                                using (tfile)
                                {
                                    string filePath = XmlDataLayer.GetUserApplicationDirectory() + "\\Temp\\" + title;
                                    tfile.CopyTo(new System.IO.FileStream(filePath, System.IO.FileMode.Create, System.IO.FileAccess.Write));
                                    XmlDataLayer.SetDownloadEntry(title);
                                    XmlDataLayer x = new XmlDataLayer();
                                    x.CombineRecentResults();
                                }
                                Console.WriteLine(title);
                            }
                            catch (Exception)
                            {
                                UploadDownloadNewFiles(false);
                            }
                            //Console.WriteLine(title);
                            //File file = service.files().get(child.Id).execute();
                        }
                        request.PageToken = children.NextPageToken;
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("An error occurred: " + e.Message);
                        request.PageToken = null;
                    }
                } while (!String.IsNullOrEmpty(request.PageToken));
                Thread.Sleep(5 * 60 * 1000);
            }
        }
        /// <summary>
        /// makes directory on google drive if it does not exist
        /// </summary>
        /// <param name="service"></param>
        /// <param name="folder"></param>
        /// <param name="parentId"></param>
        /// <returns></returns>
        private static File makeDirectoryIfNotExists(DriveService service, string folder, string parentId)
        {
            ChildrenResource.ListRequest request = service.Children.List(parentId);
            bool folderExists = false;
            File file         = null;

            do
            {
                try
                {
                    ChildList children = request.Fetch();

                    foreach (ChildReference child in children.Items)
                    {
                        //Console.WriteLine("File Id: " + child.Id);
                        file = service.Files.Get(child.Id).Fetch();
                        string title = file.Title;
                        Console.WriteLine(title);
                        if (title == folder)
                        {
                            folderExists = true;
                            break;
                        }
                        //Console.WriteLine(title);
                        //File file = service.files().get(child.Id).execute();
                    }
                    request.PageToken = children.NextPageToken;
                }
                catch (Exception e)
                {
                    Console.WriteLine("An error occurred: " + e.Message);
                    request.PageToken = null;
                }
            } while (!String.IsNullOrEmpty(request.PageToken));
            if (folderExists)
            {
                return(file);
            }

            File body = new File();

            body.Title       = folder;
            body.Description = "PCTrack_id " + XmlDataLayer.GetConfigEntry("id");
            body.MimeType    = "application/vnd.google-apps.folder";

            // Set the parent folder.
            if (!String.IsNullOrEmpty(parentId))
            {
                body.Parents = new List <ParentReference>()
                {
                    new ParentReference()
                    {
                        Id = parentId
                    }
                };
            }


            try
            {
                file = service.Files.Insert(body).Fetch();
                return(file);
            }
            catch (Exception e)
            {
                Console.WriteLine("An error occurred: " + e.Message);
                return(null);
            }
        }