<commit_before>﻿using HUSauth.Models;
using Livet;
using Livet.Commands;
using Livet.EventListeners;
using Livet.Messaging.Windows;
using Microsoft.Win32;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;

namespace HUSauth.ViewModels
{
    public class MainWindowViewModel : ViewModel
    {
        /* コマンド、プロパティの定義にはそれぞれ
         *
         *  lvcom   : ViewModelCommand
         *  lvcomn  : ViewModelCommand(CanExecute無)
         *  llcom   : ListenerCommand(パラメータ有のコマンド)
         *  llcomn  : ListenerCommand(パラメータ有のコマンド・CanExecute無)
         *  lprop   : 変更通知プロパティ(.NET4.5ではlpropn)
         *
         * を使用してください。
         *
         * Modelが十分にリッチであるならコマンドにこだわる必要はありません。
         * View側のコードビハインドを使用しないMVVMパターンの実装を行う場合でも、ViewModelにメソッドを定義し、
         * LivetCallMethodActionなどから直接メソッドを呼び出してください。
         *
         * ViewModelのコマンドを呼び出せるLivetのすべてのビヘイビア・トリガー・アクションは
         * 同様に直接ViewModelのメソッドを呼び出し可能です。
         */

        /* ViewModelからViewを操作したい場合は、View側のコードビハインド無で処理を行いたい場合は
         * Messengerプロパティからメッセージ(各種InteractionMessage)を発信する事を検討してください。
         */

        /* Modelからの変更通知などの各種イベントを受け取る場合は、PropertyChangedEventListenerや
         * CollectionChangedEventListenerを使うと便利です。各種ListenerはViewModelに定義されている
         * CompositeDisposableプロパティ(LivetCompositeDisposable型)に格納しておく事でイベント解放を容易に行えます。
         *
         * ReactiveExtensionsなどを併用する場合は、ReactiveExtensionsのCompositeDisposableを
         * ViewModelのCompositeDisposableプロパティに格納しておくのを推奨します。
         *
         * LivetのWindowテンプレートではViewのウィンドウが閉じる際にDataContextDisposeActionが動作するようになっており、
         * ViewModelのDisposeが呼ばれCompositeDisposableプロパティに格納されたすべてのIDisposable型のインスタンスが解放されます。
         *
         * ViewModelを使いまわしたい時などは、ViewからDataContextDisposeActionを取り除くか、発動のタイミングをずらす事で対応可能です。
         */

        /* UIDispatcherを操作する場合は、DispatcherHelperのメソッドを操作してください。
         * UIDispatcher自体はApp.xaml.csでインスタンスを確保してあります。
         *
         * LivetのViewModelではプロパティ変更通知(RaisePropertyChanged)やDispatcherCollectionを使ったコレクション変更通知は
         * 自動的にUIDispatcher上での通知に変換されます。変更通知に際してUIDispatcherを操作する必要はありません。
         */

        private static NotifyIcon notifyIcon;
        public Network network;

        private Version _version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;

        public string version
        {
            get { return _version.ToString(); }
        }

        public void Initialize()
        {
            ChangeStatusBarString("ネットワーク認証を確認しています");

            Settings.Initialize();

            if (Settings.ID != null || Settings.Password != "")
            {
                ID = Settings.ID;
                Password = <PASSWORD>;

                SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(SystemEvents_PowerModeChanged);
            }

            notifyIcon = new NotifyIcon();
            notifyIcon.Icon = new Icon(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("HUSauth.Views.Resource.HUSauth_tasktray.ico"));
            notifyIcon.Visible = true;

            notifyIcon.DoubleClick += (sender, e) => Restore();

            var cms = new ContextMenuStrip();
            var tsm0 = new ToolStripMenuItem();
            var tsm1 = new ToolStripMenuItem();

            tsm0.Text = "Restore";
            tsm1.Text = "Exit";
            cms.Items.AddRange(new ToolStripMenuItem[] { tsm0, tsm1 });

            tsm0.Click += (sender, e) => Restore();
            tsm1.Click += (sender, e) => Exit();

            notifyIcon.ContextMenuStrip = cms;

            network = new Network();
            var listener = new PropertyChangedEventListener(network);
            listener.RegisterHandler((sender, e) => ViewUpdateHandler(sender, e));
            this.CompositeDisposable.Add(listener);

            network.StartAuthenticationCheckTimer();

            UpdateCheck();
        }

        private async void UpdateCheck() // 本来ならここに書くべきではない気もするけどしょうがないじゃん
        {
            var uc = new UpdateChecker();
            UpdateInfoPack uip = await Task.Run(() => uc.UpdateCheck(version));

            if (uip.UpdateAvailable == true)
            {
                MessageBoxResult result = System.Windows.MessageBox.Show(
                    "新しいバージョンの HUSauth が見つかりました。\n" + uip.CurrentVersion + " -> " + uip.NextVersion + "\n\n配布サイトを開きますか？",
                    "アップデートのお知らせ",
                    MessageBoxButton.YesNo,
                    MessageBoxImage.Information);

                if (result == MessageBoxResult.Yes)
                {
                    Process.Start("http://ghippos.net/app/husauth.html");
                }
            }
        }

        private async void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
        {
            if (Network.IsAvailable() == true)
            {
                return;
            }

            network.isStarted = false;
            network.StopAuthenticationCheckTimer();

            ChangeStatusBarString("ネットワーク認証を確認しています");

            var IsConnected = false;

            try
            {
                IsConnected = await Task.Run(() => Network.IsAvailable());
            }
            catch
            {
                ChangeStatusBarString("ネットワークに接続されていません");
            }

            if (IsConnected == true)
            {
                ChangeStatusBarString("認証されています");
            }
            else
            {
                Login();

                if (IsShowTaskBar == false)
                {
                    ShowNotifyBaloon("自動認証成功", "ネットワークの自動認証に成功しました");
                }
            }

            network.StartAuthenticationCheckTimer();
        }

        #region CloseCommand

        //lvcomn<commit_msg>add) 暫定的にIPアドレスが降ってくるまで適度に待つ<commit_after>﻿using HUSauth.Models;
using Livet;
using Livet.Commands;
using Livet.EventListeners;
using Livet.Messaging.Windows;
using Microsoft.Win32;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;

namespace HUSauth.ViewModels
{
    public class MainWindowViewModel : ViewModel
    {
        /* コマンド、プロパティの定義にはそれぞれ
         *
         *  lvcom   : ViewModelCommand
         *  lvcomn  : ViewModelCommand(CanExecute無)
         *  llcom   : ListenerCommand(パラメータ有のコマンド)
         *  llcomn  : ListenerCommand(パラメータ有のコマンド・CanExecute無)
         *  lprop   : 変更通知プロパティ(.NET4.5ではlpropn)
         *
         * を使用してください。
         *
         * Modelが十分にリッチであるならコマンドにこだわる必要はありません。
         * View側のコードビハインドを使用しないMVVMパターンの実装を行う場合でも、ViewModelにメソッドを定義し、
         * LivetCallMethodActionなどから直接メソッドを呼び出してください。
         *
         * ViewModelのコマンドを呼び出せるLivetのすべてのビヘイビア・トリガー・アクションは
         * 同様に直接ViewModelのメソッドを呼び出し可能です。
         */

        /* ViewModelからViewを操作したい場合は、View側のコードビハインド無で処理を行いたい場合は
         * Messengerプロパティからメッセージ(各種InteractionMessage)を発信する事を検討してください。
         */

        /* Modelからの変更通知などの各種イベントを受け取る場合は、PropertyChangedEventListenerや
         * CollectionChangedEventListenerを使うと便利です。各種ListenerはViewModelに定義されている
         * CompositeDisposableプロパティ(LivetCompositeDisposable型)に格納しておく事でイベント解放を容易に行えます。
         *
         * ReactiveExtensionsなどを併用する場合は、ReactiveExtensionsのCompositeDisposableを
         * ViewModelのCompositeDisposableプロパティに格納しておくのを推奨します。
         *
         * LivetのWindowテンプレートではViewのウィンドウが閉じる際にDataContextDisposeActionが動作するようになっており、
         * ViewModelのDisposeが呼ばれCompositeDisposableプロパティに格納されたすべてのIDisposable型のインスタンスが解放されます。
         *
         * ViewModelを使いまわしたい時などは、ViewからDataContextDisposeActionを取り除くか、発動のタイミングをずらす事で対応可能です。
         */

        /* UIDispatcherを操作する場合は、DispatcherHelperのメソッドを操作してください。
         * UIDispatcher自体はApp.xaml.csでインスタンスを確保してあります。
         *
         * LivetのViewModelではプロパティ変更通知(RaisePropertyChanged)やDispatcherCollectionを使ったコレクション変更通知は
         * 自動的にUIDispatcher上での通知に変換されます。変更通知に際してUIDispatcherを操作する必要はありません。
         */

        private static NotifyIcon notifyIcon;
        public Network network;

        private Version _version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;

        public string version
        {
            get { return _version.ToString(); }
        }

        public void Initialize()
        {
            ChangeStatusBarString("ネットワーク認証を確認しています");

            Settings.Initialize();

            if (Settings.ID != null || Settings.Password != "")
            {
                ID = Settings.ID;
                Password = <PASSWORD>.Password;

                SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(SystemEvents_PowerModeChanged);
            }

            notifyIcon = new NotifyIcon();
            notifyIcon.Icon = new Icon(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("HUSauth.Views.Resource.HUSauth_tasktray.ico"));
            notifyIcon.Visible = true;

            notifyIcon.DoubleClick += (sender, e) => Restore();

            var cms = new ContextMenuStrip();
            var tsm0 = new ToolStripMenuItem();
            var tsm1 = new ToolStripMenuItem();

            tsm0.Text = "Restore";
            tsm1.Text = "Exit";
            cms.Items.AddRange(new ToolStripMenuItem[] { tsm0, tsm1 });

            tsm0.Click += (sender, e) => Restore();
            tsm1.Click += (sender, e) => Exit();

            notifyIcon.ContextMenuStrip = cms;

            network = new Network();
            var listener = new PropertyChangedEventListener(network);
            listener.RegisterHandler((sender, e) => ViewUpdateHandler(sender, e));
            this.CompositeDisposable.Add(listener);

            network.StartAuthenticationCheckTimer();

            UpdateCheck();
        }

        private async void UpdateCheck() // 本来ならここに書くべきではない気もするけどしょうがないじゃん
        {
            var uc = new UpdateChecker();
            UpdateInfoPack uip = await Task.Run(() => uc.UpdateCheck(version));

            if (uip.UpdateAvailable == true)
            {
                MessageBoxResult result = System.Windows.MessageBox.Show(
                    "新しいバージョンの HUSauth が見つかりました。\n" + uip.CurrentVersion + " -> " + uip.NextVersion + "\n\n配布サイトを開きますか？",
                    "アップデートのお知らせ",
                    MessageBoxButton.YesNo,
                    MessageBoxImage.Information);

                if (result == MessageBoxResult.Yes)
                {
                    Process.Start("http://ghippos.net/app/husauth.html");
                }
            }
        }

        private async void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
        {
            if (Network.IsAvailable() == true)
            {
                return;
            }

            network.isStarted = false;
            network.StopAuthenticationCheckTimer();

            ChangeStatusBarString("ネットワーク認証を確認しています");

            var IsConnected = false;

            try
            {
                IsConnected = await Task.Run(() => Network.IsAvailable());
            }
            catch
            {
                ChangeStatusBarString("ネットワークに接続されていません");
            }

            if (IsConnected == true)
            {
                ChangeStatusBarString("認証されています");
            }
            else
            {
                await Task.Run(() => Thread.Sleep(10000)); //TODO: 割り当たっているIPアドレスを確認するようにする
                Login();

                if (IsShowTaskBar == false)
                {
                    ShowNotifyBaloon("自動認証成功", "ネットワークの自動認証に成功しました");
                }
            }

            network.StartAuthenticationCheckTimer();
        }

        #region CloseCommand

        //lvcomn
{'fraction_non_alphanumeric': 0.08383940620782726, 'fraction_numerical': 0.0024460188933873145, 'mean_word_length': 2.0488557469786577, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4726998', 'n_tokens_mistral': 4247, 'n_tokens_neox': 4034, 'n_words': 459}