private async Task LoadImage(bool isRefresh = false)
        {
            await Task.Delay(100);

            try
            {
                fairyImageView.SetImageDrawable(null);
                imageDrawable?.Dispose();
                loadingLayout.Visibility = ViewStates.Visible;
                loadingIndicator.SmoothToShow();
                loadingText.SetText(Resource.String.Common_Load);

                string imageName = $"{fairy.DicNumber}_{imageNum}";
                string imagePath = Path.Combine(ETC.cachePath, "Fairy", "Normal", $"{imageName}.gfdcache");
                string url       = Path.Combine(ETC.server, "Data", "Images", "Fairy", "Normal", $"{imageName}.png");

                if (!File.Exists(imagePath) || isRefresh)
                {
                    string dTemp = Resources.GetString(Resource.String.Common_Downloading);

                    loadingText.Text = dTemp;

                    using (var wc = new WebClient())
                    {
                        wc.DownloadProgressChanged += (sender, e) => { loadingText.Text = $"{dTemp}{e.ProgressPercentage}%"; };

                        await wc.DownloadFileTaskAsync(url, imagePath);
                    }
                }

                await Task.Delay(500);

                loadingText.SetText(Resource.String.Common_Load);

                imageDrawable = await Drawable.CreateFromPathAsync(imagePath);

                fairyImageView.SetImageDrawable(imageDrawable);

                fairyNumTitle.Text = $"{imageNum} 단계";
                imageStatus.Text   = $"{fairy.Name} - {imageNum}단계";
            }
            catch (Exception ex)
            {
                ETC.LogError(ex, this);
                ETC.ShowSnackbar(snackbarLayout, Resource.String.ImageLoad_Fail, Snackbar.LengthLong, Android.Graphics.Color.DarkRed);
            }
            finally
            {
                loadingText.Text = "";
                loadingIndicator.SmoothToHide();
                loadingLayout.Visibility = ViewStates.Gone;
            }
        }
        private async Task <bool> DownloadImage()
        {
            try
            {
                loadingIndicator.SmoothToShow();

                if (!await CheckExistGuideImage())
                {
                    loadingIndicator.SmoothToHide();
                    loadingText.SetText(Resource.String.DollDBGuideImageViewer_LoadingText_NotExistServerImage);

                    return(false);
                }

                string defaultText = Resources.GetString(Resource.String.DollDBGuideImageViewer_LoadingText_DownloadImage);

                loadingText.Text = defaultText;

                await Task.Delay(500);

                using (var wc = new WebClient())
                {
                    wc.DownloadProgressChanged += (sender, e) => { loadingText.Text = $"{defaultText}{e.ProgressPercentage}%"; };

                    await wc.DownloadFileTaskAsync(serverImagePath, localImagePath);
                }

                await Task.Delay(500);
            }
            catch (Exception ex)
            {
                ETC.LogError(ex, this);
                loadingIndicator.SmoothToHide();
                loadingText.SetText(Resource.String.DollDBGuideImageViewer_LoadingText_FailDownloadImage);

                return(false);
            }

            return(true);
        }
        private async Task ProcessData()
        {
            try
            {
                isLoading = true;

                loadingIndicatorExplain.SetText(Resource.String.ProductPercentTable_LoadingText_ReceiveServerData);

                string url = $"{topURL}{id}";
                string tempData;

                using (WebClient wc = new WebClient())
                {
                    tempData = await wc.DownloadStringTaskAsync(url);
                }

                loadingIndicatorExplain.SetText(Resource.String.ProductPercentTable_LoadingText_DataProcess);

                StringBuilder sb = new StringBuilder(tempData);

                sb.Replace("\"formula\":", " ");

                List <int> removeList = new List <int>();

                for (int i = 0; i < sb.Length; ++i)
                {
                    if ((sb[i] == '[') || (sb[i] == ']') || (sb[i] == '{') || (sb[i] == '}') || (char.IsWhiteSpace(sb[i])))
                    {
                        removeList.Add(i);
                    }
                }

                removeList.TrimExcess();

                int count = 0;

                foreach (int index in removeList)
                {
                    if ((index - count) >= 0)
                    {
                        sb.Remove((index - count), 1);
                    }
                    else
                    {
                        sb.Remove(0, 1);
                    }

                    count += 1;
                }

                await Task.Delay(100);

                tempData = sb.ToString();

                loadingIndicatorExplain.SetText(Resource.String.ProductPercentTable_LoadingText_DataListing);

                string[] data = tempData.Split(',');

                int        normalCount  = 0;
                List <int> normalRow    = new List <int>();
                int        advanceCount = 0;
                List <int> advanceRow   = new List <int>();

                for (int i = 0; i < (data.Length / 8); ++i)
                {
                    int type = int.Parse(data[((i * 8) + 5)].Split(':')[1]);

                    switch (type)
                    {
                    case 0:
                    default:
                        normalCount += 1;
                        normalRow.Add(i);
                        break;

                    case 2:
                        advanceCount += 1;
                        advanceRow.Add(i);
                        break;
                    }
                }

                normalRow.TrimExcess();
                advanceRow.TrimExcess();

                normalData  = new double[normalCount, 9];
                advanceData = new double[advanceCount, 9];

                for (int i = 0; i < (normalData.Length / topViewIds.Length); ++i)
                {
                    int row = normalRow[i];

                    if (i == 197)
                    {
                        await Task.Delay(1);
                    }

                    for (int j = 0; j < topViewIds.Length; j++)
                    {
                        normalData[i, j] = (j == 8) ? Math.Round(((normalData[i, 6] / normalData[i, 7]) * 100), 4) :
                                           double.Parse(data[((row * 8) + j)].Split(':')[1]);

                        /*if (j == 8) normalData[i, j] = Math.Round(((normalData[i, 6] / normalData[i, 7]) * 100), 4);
                         * else normalData[i, j] = double.Parse(data[((row * 8) + j)].Split(':')[1]);*/
                    }
                }

                if (advanceCount != 0)
                {
                    for (int i = 0; i < (advanceData.Length / topViewIds.Length); ++i)
                    {
                        int row = advanceRow[i];

                        for (int j = 0; j < topViewIds.Length; j++)
                        {
                            advanceData[i, j] = (j == 8) ? Math.Round(((advanceData[i, 6] / advanceData[i, 7]) * 100), 4) :
                                                int.Parse(data[((row * 8) + j)].Split(':')[1]);

                            /*if (j == 8) advanceData[i, j] = Math.Round(((advanceData[i, 6] / advanceData[i, 7]) * 100), 4);
                             * else advanceData[i, j] = int.Parse(data[((row * 8) + j)].Split(':')[1]);*/
                        }
                    }
                }

                await Task.Delay(500);

                _ = LoadList();
            }
            catch (Exception ex)
            {
                ETC.LogError(ex, this);
            }
            finally
            {
                loadingIndicatorView.SmoothToHide();
                loadingIndicatorExplain.Visibility = ViewStates.Gone;
            }
        }
        private async Task LoadImage(int costumeIndex, bool isRefresh = false)
        {
            await Task.Delay(100);

            string imageName = doll.DicNumber.ToString();

            try
            {
                dollImageView.SetImageDrawable(null);
                imageDrawable?.Dispose();
                loadingLayout.Visibility = ViewStates.Visible;
                loadingIndicator.SmoothToShow();
                MainThread.BeginInvokeOnMainThread(() => { loadingText.SetText(Resource.String.Common_Load); });

                if (costumeIndex >= 1)
                {
                    imageName += $"_{costumeIndex + 1}";
                }
                else if ((costumeIndex == 0) && (modIndex == 3))
                {
                    imageName += "_M";
                }

                imageName += isDamage ? "_D" : "";

                if (doll.HasCensored && enableCensored && (modIndex != 3))
                {
                    imageName += CheckCensorType() ? "_C" : "";
                }

                string imagePath = Path.Combine(ETC.cachePath, "Doll", "Normal", $"{imageName}.gfdcache");
                string url       = Path.Combine(ETC.server, "Data", "Images", "Guns", "Normal", $"{imageName}.png");

                if (!File.Exists(imagePath) || isRefresh)
                {
                    string dTemp = Resources.GetString(Resource.String.Common_Downloading);

                    MainThread.BeginInvokeOnMainThread(() => { loadingText.Text = dTemp; });

                    using (var wc = new WebClient())
                    {
                        wc.DownloadProgressChanged += (sender, e) => { loadingText.Text = $"{dTemp}{e.ProgressPercentage}%"; };

                        await wc.DownloadFileTaskAsync(url, imagePath);
                    }
                }

                await Task.Delay(500);

                MainThread.BeginInvokeOnMainThread(() => { loadingText.SetText(Resource.String.Common_Load); });

                imageDrawable = await Drawable.CreateFromPathAsync(imagePath);

                dollImageView.SetImageDrawable(imageDrawable);

                string damageText = isDamage ? Resources.GetString(Resource.String.DollDBImageViewer_ImageStatusDamage) : Resources.GetString(Resource.String.DollDBImageViewer_ImageStatusNormal);
                string censorText = Resources.GetString(Resource.String.DollDBImageViewer_ImageCensored);

                imageStatus.Text = censorMenuItem.IsVisible ? $"{doll.Name} - {costumes[costumeIndex]} - {damageText} - {censorText}{(enableCensored ? "O" : "X")}" :
                                   $"{doll.Name} - {costumes[costumeIndex]} - {damageText}";
            }
            catch (WebException ex)
            {
                ETC.LogError(ex, this);
                ETC.ShowSnackbar(snackbarLayout, Resource.String.ImageLoad_Fail, Snackbar.LengthLong, Android.Graphics.Color.DarkRed);
            }
            catch (Exception ex)
            {
                ETC.LogError(ex, this);
                ETC.ShowSnackbar(snackbarLayout, Resource.String.ImageLoad_Fail, Snackbar.LengthLong, Android.Graphics.Color.DarkRed);
            }
            finally
            {
                loadingText.Text = "";
                loadingIndicator.SmoothToHide();
                loadingLayout.Visibility = ViewStates.Gone;
            }
        }