using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Formatting;
//using Newtonsoft.Json;
//using Newtonsoft.Json.Serialization;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Ionic.Zip;
namespace JsonClient
{
class ExtentsionCalendar : PictureBox
{
int _dtf;//指定年月の初日の曜日を取得
int _dte;//指定年月の日数
int _dtbei;//指定年月の前月の日数
int _d;//今日の日付
string _nowst;//今日の日付
List<Label> arname = new List<Label>();//曜日名
List<Label> ardt = new List<Label>();//日付のLabel
List<Label> nowl = new List<Label>();//当月の日付のLabel
const int PX_SIZE = 250;
const int PY_SIZE = 165;
const int TX_SIZE = 30;
const int TY_SIZE = 18;
Font fnt = new Font("MS UI Gothic", 13, FontStyle.Bold); //フォントサイズ
Font fnts = new Font("MS UI Gothic", 13, FontStyle.Regular); //フォントサイズ
private Thread IcThread;
private Thread IcTeikiThread;
private Thread CashThread;
private Thread WaitThread;
private delegate void GetStatusType(CalendarType type);
// TODO ラベルを作成するメソッド作成、ラベルを作成するメソッド用のデリゲートを作成?
private delegate void ShowPictureBoxEvent();
private ManualResetEvent IcResetEvent;
private ManualResetEvent IcTeikiResetEvent;
private ManualResetEvent CashResetEvent;
private object syncObject = new object();
private bool isShowCal = false;
private ProcType CalendarProcType { get; set; }
private Dictionary<string, string> DateLabels = new Dictionary<string, string>();
// TODO 更新中フラグ
private bool isUpdating = false;
private bool isShowCalendar
{
get
{
return isShowCal;
}
set
{
lock(syncObject)
{
isShowCal = value;
}
}
}
private TextBox textBox1;
private TextBox textBox2;
enum CalendarType
{
ICDtl,
ICTeikiDtl,
CashDtl,
None
}
enum ProcType
{
Daily,
Monthly,
}
enum StatusType
{
Disable,
Available,
Reserved
}
//指定年月の初日の曜日の読み取り
public int dtf
{
get { return this._dtf; }
}
//指定年月の日数の読み取り
public int dte
{
get { return this._dte; }
}
//指定年月の前月の日数の読み取り
public int dtbei
{
get { return this._dtbei; }
}
//今日の日付の読み取り
public int d
{
get { return this._d; }
}
//今日の日付 年 月
public string nowst
{
get { return this._nowst; }
}
public ExtentsionCalendar()
{
}
public void UpdateCalendar()
{
IcResetEvent = new ManualResetEvent(false);
IcTeikiResetEvent = new ManualResetEvent(false);
CashResetEvent = new ManualResetEvent(false);
// 読み込み中状態に設定
isShowCalendar = false;
ShowPictureBox();
WaitThread = new Thread(new ThreadStart(ModifyCalendarData));
WaitThread.Start();
//wait状態になるまで処理を続行しない
while (!isUpdating) { Thread.Sleep(100); }
IcThread = new Thread(new ParameterizedThreadStart(this.CalendarProc));
IcThread.Start(CalendarType.ICDtl);
IcTeikiThread = new Thread(new ParameterizedThreadStart(this.CalendarProc));
IcTeikiThread.Start(CalendarType.ICTeikiDtl);
CashThread = new Thread(new ParameterizedThreadStart(this.CalendarProc));
CashThread.Start(CalendarType.CashDtl);
}
public void Init(TextBox yearTextBox, TextBox monthTextBox)
{
// 画面の初期表示時のラジオボタンで判断を変更できるようにする
CalendarProcType = ProcType.Daily;
// コントロールを取得
textBox1 = yearTextBox;
textBox2 = monthTextBox;
}
private void CalendarProc(object calType)
{
CalendarType type = (CalendarType)calType;
switch (type)
{
case CalendarType.ICDtl:
case CalendarType.ICTeikiDtl:
case CalendarType.CashDtl:
int iLoopCount = (CalendarProcType == ProcType.Daily ? 4 : 2);
//int iLoopCount = 1;
string path = "";
try
{
for (int i = 0; i < iLoopCount; i++)
{
path = @"http://localhost:65339/" + Enum.GetName(typeof(CalendarType), calType) + Enum.GetName(typeof(ProcType), CalendarProcType) + (i + 1).ToString() + ".ashx";
using (HttpClient client = new HttpClient() { Timeout = TimeSpan.FromMinutes(10) })
{
// Get
var response = client.GetAsync(path).Result;
response.EnsureSuccessStatusCode();
response.Content.LoadIntoBufferAsync();
switch (type)
{
case CalendarType.ICDtl:
SingletonStatusData.Instance().IcStatusList.AddRange(response.Content.ReadAsAsync<ReductionStatusData>().Result.Result);
break;
case CalendarType.ICTeikiDtl:
SingletonStatusData.Instance().IcTeikiStatusList.AddRange(response.Content.ReadAsAsync<ReductionStatusData>().Result.Result);
break;
case CalendarType.CashDtl:
SingletonStatusData.Instance().CashStatusList.AddRange(response.Content.ReadAsAsync<ReductionStatusData>().Result.Result);
break;
}
}
}
}
catch (Exception)
{
}
finally
{
switch (type)
{
case CalendarType.ICDtl:
IcResetEvent.Set();
break;
case CalendarType.ICTeikiDtl:
IcTeikiResetEvent.Set();
break;
case CalendarType.CashDtl:
CashResetEvent.Set();
break;
}
}
break;
}
}
private void ModifyCalendarData()
{
isUpdating = true;
IcResetEvent.WaitOne();
IcTeikiResetEvent.WaitOne();
CashResetEvent.WaitOne();
// TODO エラーがあれば処理
// TODO どうやってエラーメッセージにする?
if(!isUpdating)
{
isShowCalendar = false;
this.Invoke(new MethodInvoker(ShowPictureBox));
}
List<ReductionStatusData.ResultData> result = new List<ReductionStatusData.ResultData>();
result.AddRange(SingletonStatusData.Instance().IcStatusList);
result.AddRange(SingletonStatusData.Instance().IcTeikiStatusList);
result.AddRange(SingletonStatusData.Instance().CashStatusList);
List<int> result2 = new List<int>();
DateTime now = DateTime.Now;
DateLabels.Clear();
if (CalendarProcType == ProcType.Monthly)
{
now = new DateTime(now.Year - 1, 1, 1);
// 二年分のデータを取得
for (int i = 0; i < 24; i++)
{
result2 = result.Where(x => x.Date == now.AddMonths(i).ToString("yyyy/MM")).Select(o => o.StatusCd).ToList();
if (result2.Count == 0)
{
// TODO 何か処理を実施
//throw new Exception("データなし");
}
else
{
// TODO 今のところ、取得した値の中で一番小さい値を取得しているけど、仕様書をみて正しい値を見る
DateLabels.Add(now.AddMonths(i).ToString("yyyyMMdd"), result2.Distinct().Min().ToString());
}
}
}
else
{
now = new DateTime(now.Year, now.Month - 3, 1);
int iLoopDateCount = 0;
for (int iLoop = 0; iLoop < 4; iLoop++)
{
iLoopDateCount += DateTime.DaysInMonth(now.Year, now.Month + iLoop);
}
// 今月+3か月分のデータを取得
for (int i = 0; i < iLoopDateCount; i++)
{
result2 = result.Where(x => x.Date == now.AddDays(i).ToString("yyyy/MM/dd")).Select(o => o.StatusCd).ToList();
if (result2.Count == 0)
{
// TODO 何か処理を実施
//throw new Exception("データなし");
}
else
{
// TODO 今のところ、取得した値の中で一番小さい値を取得しているけど、仕様書をみて正しい値を見る
DateLabels.Add(now.AddDays(i).ToString("yyyyMMdd"), result2.Distinct().Min().ToString());
}
}
}
isShowCalendar = true;
this.Invoke(new MethodInvoker(ShowPictureBox));
}
private void ShowPictureBox()
{
lock (syncObject)
{
if (!isShowCalendar)
{
this.Image = null;
////200x100サイズのImageオブジェクトを作成する
//Bitmap img = new Bitmap(200, 100);
////ImageオブジェクトのGraphicsオブジェクトを作成する
//Graphics g = Graphics.FromImage(img);
////全体を黒で塗りつぶす
//g.FillRectangle(Brushes.Black, g.VisibleClipBounds);
////黄色い扇形を描画する
//g.DrawPie(Pens.Yellow, 60, 10, 80, 80, 30, 300);
//g.DrawString("読み込み中です...")
////リソースを解放する
//g.Dispose();
////作成した画像を表示する
//this.Image = img;
this.Size = new Size(PX_SIZE, PY_SIZE);
this.Image = new Bitmap(PX_SIZE,PY_SIZE);
using (Font font = new Font("メイリオ", 15))
using (Graphics graphics = Graphics.FromImage(this.Image))
{
graphics.DrawString("更新中です...",
font,
new SolidBrush(Color.Black),
new Point(PX_SIZE / 2, PY_SIZE / 2),
new StringFormat() { LineAlignment = StringAlignment.Center, Alignment = StringAlignment.Center }
);
}
//this.Image = null;
}
else
{
this.Image = null;
nowdt();
this.BackColor = Color.Aqua;
this.Size = new Size(PX_SIZE, PY_SIZE);
//曜日のLabelの作成
for (int k1 = 0; k1 < 7; ++k1)
{
Label namelb = new Label();
namelb.BackColor = Color.White;
namelb.Size = new Size(TX_SIZE, TY_SIZE);
namelb.Location = new Point(5 + (TX_SIZE + 5) * k1, 5);
namelb.Font = fnt;
namelb.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
arname.Add(namelb);
this.Controls.Add(namelb);
}
arname[0].Text = "日";
arname[1].Text = "月";
arname[2].Text = "火";
arname[3].Text = "水";
arname[4].Text = "木";
arname[5].Text = "金";
arname[6].Text = "土";
//日付のLabelの作成
for (int i2 = 0; i2 < 6; ++i2)
{
for (int i1 = 0; i1 < 7; ++i1)
{
Label lb = new Label();
lb.BackColor = Color.White;
lb.Size = new Size(TX_SIZE, TY_SIZE);
lb.Location = new Point(5 + (TX_SIZE + 5) * i1, TY_SIZE + 9 + (TY_SIZE + 5) * i2);
lb.Font = fnt;
lb.TextAlign = ContentAlignment.MiddleCenter;
ardt.Add(lb);
this.Controls.Add(lb);
lb.Click += new EventHandler(LB_CLICK);//イベント
}
}
//日曜日を赤くします
for (int fr = 0; fr < 6; ++fr)
{
ardt[7 * fr].ForeColor = Color.Red;
}
button1_Click(null, null);
}
}
}
//初期のカレンダーデータ
public void nowdt()
{
DateTime ndt = DateTime.Now;
int y = ndt.Year;
int m = ndt.Month;
_d = ndt.Day;
txtdt(y.ToString(), m.ToString());
_nowst = y.ToString() + "年" + m.ToString() + "月";
}
//Class Form1からTextBox1,TextBox2の値を取得
public void txtdt(string txt1, string txt2)
{
string ntxt2 = (Convert.ToInt32(txt2) - 1).ToString();
// '年月日を"2004/02/01"の形式にする
string dtstring = txt1 + "/" + txt2 + "/" + "01";//指定日の日にち
string dtstbe = txt1 + "/" + ntxt2 + "/" + "01";//指定年月の前月の日にち
//指定日の曜日を取得する
DateTime dt1;//指定年月
DateTime dt2;//指定年月の前月
//指定年月の月が1月の場合は前年の12月にする
int ctxt1;
if (txt2 == "1")
{
ctxt1 = Convert.ToInt32(txt1) - 1;
dtstbe = ctxt1.ToString() + "/12/31";
}
if (DateTime.TryParse(dtstring, out dt1))
{
//何もしない
}
else
{
MessageBox.Show("日付に変換できない数字が入力されました。");
}
if (DateTime.TryParse(dtstbe, out dt2))
{
//何もしない
}
else
{
MessageBox.Show("日付に変換できない数字が入力されました。");
}
calk(dt1, dt2);
}
//
private void calk(DateTime d1, DateTime d2)
{
//指定年月の初日の曜日を取得する
_dtf = Convert.ToInt32(d1.DayOfWeek);
//指定年月の日数を取得する
_dte = DateTime.DaysInMonth(d1.Year, d1.Month);
//指定年月の前月の日数を取得する
_dtbei = DateTime.DaysInMonth(d2.Year, d2.Month);
}
//Labelをクリックすると枠が付きます。
private void LB_CLICK(object sender, EventArgs e)
{
Label lb = sender as Label;
int px = lb.Location.X;
int py = lb.Location.Y;
int lsw = lb.Width;
int lsh = lb.Height;
Pen pn = new Pen(Color.Blue, 5);
Bitmap space = new Bitmap(this.Width, this.Height);
Graphics g = Graphics.FromImage(space);
g.DrawRectangle(pn, px - 3, py - 1, lsw + 3, lsh + 1);
g.Dispose();
this.Image = space;
}
public void button1_Click(object sender, EventArgs e)
{
nowl.Clear();
txtdt(textBox1.Text, textBox2.Text);
//一度カレンダーを空にする
foreach (Label lbst in ardt)
{
lbst.Text = "";
}
int p = 0;//日にち
for (int d = dtf; d < dte + dtf; ++d)
{
p += 1;
ardt[d].Text = p.ToString();
nowl.Add(ardt[d]);//当月の日付のLabelをAddする
}
//前月のカレンダー
int be = 0;
for (int bef = 0; bef < dtf; ++bef)
{
ardt[bef].Font = fnts;
be += 1;
ardt[bef].Text = (dtbei - dtf + be).ToString();
}
//翌月のカレンダー
int af = 0;
for (int aft = be + dte; aft < ardt.Count; ++aft)
{
ardt[aft].Font = fnts;
af += 1;
ardt[aft].Text = af.ToString();
}
}
}
}