private async Task UploadItem(UploadQueueItem uploadQueueItem, DataChunkSize dataChunkSize)
        {
            if (uploadQueueItem.Title.Trim().Length == 0)
            {
                App.TaskDialogShow("오류", "입력에 오류가 있습니다.", "영상 제목은 반드시 채워져야 합니다.",
                                   TaskDialogIcon.Error, TaskDialogCommonButtonFlags.OK);
                return;
            }

            string itemName = $"{uploadQueueItem.Title}({Path.GetFileName ( HttpUtility.UrlDecode ( uploadQueueItem.FileName.AbsolutePath ) )})";

            switch (await uploadQueueItem.UploadStart(dataChunkSize))
            {
            case UploadResult.Succeed:
                switch (uploadQueueItem.UploadingStatus)
                {
                case UploadingStatus.UploadCompleted: NotificatorManager.Notify("안내", $"{itemName}에 대한 업로드를 성공했습니다.", NotifyType.CustomType1); break;

                case UploadingStatus.UpdateComplete: NotificatorManager.Notify("안내", $"{itemName}에 대한 업데이트를 성공했습니다.", NotifyType.CustomType1); break;

                case UploadingStatus.UploadFailed: NotificatorManager.Notify("안내", $"{itemName}에 대한 업로드를 실패했습니다.", NotifyType.Warning); break;

                case UploadingStatus.UpdateFailed: NotificatorManager.Notify("안내", $"{itemName}에 대한 업데이트를 실패했습니다.", NotifyType.Warning); break;
                }
                break;

            case UploadResult.UploadCanceled: NotificatorManager.Notify("안내", $"{itemName}에 대한 업로드가 중단됐습니다.\n업로드 재개가 가능합니다.", NotifyType.Warning); break;

            case UploadResult.AlreadyUploading: NotificatorManager.Notify("오류", $"{itemName}은 이미 업로드가 시작되었습니다.", NotifyType.Error); break;

            case UploadResult.FailedUploadRequest: NotificatorManager.Notify("오류", $"{itemName}의 업로드 요청을 시작할 수 없었습니다.", NotifyType.Error); break;

            case UploadResult.CannotStartUpload: NotificatorManager.Notify("오류", $"{itemName}의 업로드 작업을 시작할 수 없었습니다.", NotifyType.Error); break;
            }
        }
        private async void Window_Loaded(object sender, RoutedEventArgs e)
        {
            if (YouTubeSession.IsAlreadyAuthorized)
            {
                ButtonConnect_Click(sender, e);
            }

            notificationToggleCheckBox.DataContext = NotificatorManager.Notificator;
            notificationToggleCheckBox.SetBinding(CheckBox.IsCheckedProperty, new Binding(nameof(NotificatorManager.Notificator.IsEnabledNotification))
            {
                Mode = BindingMode.TwoWay,
            });

            if (await updateChecker.CheckUpdate() == true)
            {
                NotificatorManager.Notify("업데이트 확인", "Daram YouTube Uploader의 최신 버전이 있습니다.", NotifyType.Information);
            }
        }
        public MainWindow()
        {
            SharedWindow = this;

            updateChecker = new UpdateChecker("v{0}.{1}{2}");

            //InitializeNotificatorImages ();

            Stream iconStream = Application.GetResourceStream(new Uri("pack://application:,,,/DaramYouTubeUploader;component/Resources/MainIcon.ico")).Stream;

            NotificatorManager.Initialize(new NotificatorInitializer()
            {
                AppId = "Daramee.YouTubeUploader",

                Title = "다람 유튜브 업로더",
                Icon  = new System.Drawing.Icon(iconStream, 16, 16),

                WarningTypeImagePath     = Path.Combine(tempPath, "WarningIcon.png"),
                InformationTypeImagePath = Path.Combine(tempPath, "InformationIcon.png"),
                ErrorTypeImagePath       = Path.Combine(tempPath, "ErrorIcon.png"),
                CustomTypeImagePath1     = Path.Combine(tempPath, "SucceedIcon.png"),

                ForceLegacy = true
            });
            iconStream.Dispose();
            NotificatorManager.Notificator.Clicked += (sender2, e2) =>
            {
                Dispatcher.BeginInvoke(new Action(() =>
                {
                    if (WindowState == WindowState.Minimized)
                    {
                        WindowState = WindowState.Normal;
                    }
                    Activate();
                }));
            };

            option = new Optionizer <SaveData> ("DARAM WORLD", "DaramYouTubeUploader");

            InitializeComponent();
            TaskbarItemInfo = new TaskbarItemInfo();

            uploadQueueListBox.ItemsSource = new ObservableCollection <UploadQueueItem> ();
        }
        private void AddItem(string filename)
        {
            if (!YouTubeSession.IsAlreadyAuthorized)
            {
                return;
            }

            bool alreadyAdded = false;
            Uri  filenameUri  = new Uri(filename);

            foreach (var item in uploadQueueListBox.ItemsSource as IList <UploadQueueItem> )
            {
                if (item.FileName.AbsolutePath == filenameUri.AbsolutePath)
                {
                    alreadyAdded = true;
                    break;
                }
            }

            if (alreadyAdded)
            {
                return;
            }

            string          itemName = Path.GetFileName(filename);
            UploadQueueItem queueItem;

            try
            {
                queueItem = new UploadQueueItem(YouTubeSession, filename)
                {
                    PrivacyStatus = ( PrivacyStatus )comboBoxDefaultPrivacyStatus.SelectedIndex
                };
            }
            catch (ArgumentException)
            {
                NotificatorManager.Notify("오류", $"{itemName}의 업로드할 파일의 크기는 64GB를 넘길 수 없습니다.", NotifyType.Error);
                return;
            }
            catch (IOException)
            {
                NotificatorManager.Notify("오류", $"{itemName}의 영상 파일에 접근할 수 없었습니다.", NotifyType.Error);
                return;
            }

            // 업로드 성공
            queueItem.Completed += (sender, e) =>
            {
                if (DeleteWhenComplete)
                {
                    File.Delete(System.Web.HttpUtility.UrlDecode((sender as UploadQueueItem).FileName.AbsolutePath));
                }

                if (HaltWhenAllCompleted)
                {
                    var  list        = uploadQueueListBox.ItemsSource as IList <UploadQueueItem>;
                    bool incompleted = false;
                    foreach (var i in list)
                    {
                        if (i.UploadingStatus == UploadingStatus.UploadCompleted || i.UploadingStatus == UploadingStatus.UpdateComplete)
                        {
                            continue;
                        }
                        incompleted = true;
                        break;
                    }

                    if (!incompleted)
                    {
                        Dispatcher.BeginInvoke(new Action(() => { new HaltWindow().ShowDialog(); }));
                    }
                }
            };
            // 업로드 실패
            queueItem.Failed += async(sender, e) =>
            {
                if ((sender as UploadQueueItem).UploadingStatus == UploadingStatus.UploadCompleted ||
                    (sender as UploadQueueItem).UploadingStatus == UploadingStatus.UpdateComplete ||
                    (sender as UploadQueueItem).UploadingStatus == UploadingStatus.UploadCanceled)
                {
                    return;
                }
                if ((sender as UploadQueueItem).IsManuallyPaused)
                {
                    return;
                }
                if (!HaltWhenAllCompleted && !RetryWhenCanceled)
                {
                    return;
                }

                int sec = 0;
                switch (option.Options.RetryDelayIndex)
                {
                case 0: sec = 0; break;

                case 1: sec = 5; break;

                case 2: sec = 10; break;

                case 3: sec = 15; break;

                case 4: sec = 30; break;

                case 5: sec = 60; break;
                }
                if (sec != 0)
                {
                    await Task.Delay(1000 *sec);
                }

                if (!HaltWhenAllCompleted && !RetryWhenCanceled)
                {
                    return;
                }
                var uploadState = (sender as UploadQueueItem).UploadingStatus;
                if (uploadState == UploadingStatus.Uploading || uploadState == UploadingStatus.UploadCompleted || uploadState == UploadingStatus.UpdateComplete)
                {
                    return;
                }

                await(sender as UploadQueueItem).UploadStart();
            };
            // 업로드 중
            queueItem.Uploading += (sender, e) =>
            {
                Dispatcher.BeginInvoke(new Action(() =>
                {
                    double totalProgress   = 0;
                    bool thereIsFailedItem = false;
                    int totalCount         = 0;

                    foreach (var item in uploadQueueListBox.ItemsSource as ObservableCollection <UploadQueueItem> )
                    {
                        if (item.UploadingStatus == UploadingStatus.UploadFailed || item.UploadingStatus == UploadingStatus.UpdateFailed)
                        {
                            thereIsFailedItem = true;
                        }
                        else if (item.UploadingStatus == UploadingStatus.Queued)
                        {
                            continue;
                        }
                        totalProgress += item.Progress;
                        ++totalCount;
                    }

                    TaskbarItemInfo.ProgressState = thereIsFailedItem ? TaskbarItemProgressState.Paused : TaskbarItemProgressState.Normal;
                    TaskbarItemInfo.ProgressValue = totalProgress / totalCount;
                }));
            };
            (uploadQueueListBox.ItemsSource as IList <UploadQueueItem>).Add(queueItem);
        }
 private void Window_Closed(object sender, EventArgs e)
 {
     NotificatorManager.Uninitialize();
     option.Save();
 }