unit NetVoteWin;

{$WARN UNIT_PLATFORM OFF}
{$WARN SYMBOL_PLATFORM OFF}

interface

uses
  Windows, SysUtils, Forms, Dialogs, Classes, Controls, StdCtrls, Buttons, ComCtrls,
  ExtCtrls, Grids, Graphics,
  IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, Menus, _NetVote_const;

type
  TNetVote = class(TForm)
    VotePanel: TPanel;
    SeekGrid: TStringGrid;
    InfoLbl: TStaticText;
    RefreshShape: TShape;
    RefreshLbl: TLabel;
    CloseLbl: TLabel;
    CloseShape: TShape;
    GripImg: TImage;
    SizeChangeTimer: TTimer;
    RefreshVoteTimer: TTimer;
    MaxCountLst: TComboBox;
    VoteLbl: TLabel;
    VoteShape: TShape;
    SortLbl: TLabel;
    SortShape: TShape;
    TitleLbl: TStaticText;
    MenuLbl: TLabel;
    MenuShape: TShape;
    PopupMenu: TPopupMenu;
    PM_2lineComment: TMenuItem;
    FontDlg: TFontDialog;
    PM_ListFont: TMenuItem;
    SeekGridImg: TImage;
    procedure FormCreate(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure SeekGridDblClick(Sender: TObject);
    procedure SeekEdtKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure SeekGridKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure InfoLblMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure InfoLblMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure InfoLblMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure VotePanelMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure VotePanelMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure VotePanelMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure CloseLblClick(Sender: TObject);
    procedure SeekGridMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure SeekGridMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure SeekGridMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure GripImgMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure GripImgMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure GripImgMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure SizeChangeTimerTimer(Sender: TObject);
    procedure RefreshLblClick(Sender: TObject);
    procedure RefreshVoteTimerTimer(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure MaxCountLstChange(Sender: TObject);
    procedure SeekGridMouseWheelDown(Sender: TObject; Shift: TShiftState;
      MousePos: TPoint; var Handled: Boolean);
    procedure SeekGridMouseWheelUp(Sender: TObject; Shift: TShiftState;
      MousePos: TPoint; var Handled: Boolean);
    procedure SeekGridDrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
    procedure VoteLblClick(Sender: TObject);
    procedure SortLblClick(Sender: TObject);
    procedure MenuLblClick(Sender: TObject);
    procedure PM_2lineCommentClick(Sender: TObject);
    procedure PM_ListFontClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private 宣言 }
    VoteData:TVoteData;
    MBarFlag:boolean;
    MBarX,MBarY:integer;
    DlgDrag:boolean;
    Dlgmx:integer;
    Dlgmy:integer;
    MaxCountChangeHold:boolean;
    procedure ReflectSeekGridFont;
    procedure RefreshVote;
    procedure RefreshGrid;
    procedure RefreshTitle;
    procedure ClearGrid;
    function ProcessVote(Vote:TVote):boolean;
    procedure ProcessVoteOnStatus(ASender: TObject; const AStatus: TIdStatus; const AStatusText: String);
    procedure ExtractURL(const url:string;var path,filename:string);
    procedure SetGridRowCount(cnt:integer);
  public
    { Public 宣言 }
    procedure LoadSkin;
    procedure Init;
  end;

var
  NetVote: TNetVote;

implementation

uses MainWin, SetVoteDlg,
     _MDXWinINI,_MainFileCtl, _GridTool, _m_Tools, _PicTools,_Images,
     _netconst,_GridScroll,_GridScroll_Rap,_CSkin;

{$R *.dfm}

procedure SetShapeLblColor(var Lbl:TLabel;var Shape:TShape;const mode:boolean);
begin
  if mode=True then begin
    Lbl.Font.Color:=CSkin.dwEtcBright;
    Shape.Pen.Color:=CSkin.dwEtcBright;
    end else begin
    Lbl.Font.Color:=CSkin.dwEtcMask;
    Shape.Pen.Color:=CSkin.dwEtcMask;
  end;
end;

procedure TNetVote.LoadSkin;
  procedure SetLabel(var Lb:TStaticText);
  begin
    Lb.Color:=CSkin.dwEtcBG;
    Lb.Font.Color:=CSkin.dwEtcBright;
  end;
  procedure SetEdit(var Edt:TEdit);
  begin
    Edt.Color:=CSkin.dwEtcBG;
    Edt.Font.Color:=CSkin.dwEtcText;
  end;
  procedure SetCLst(var CLst:TComboBox);
  begin
    CLst.Color:=CSkin.dwEtcBG;
    CLst.Font.Color:=CSkin.dwEtcBright;
  end;
begin
  MakeBlankImg(GripImg,pf24bit);
  with GripImg do begin
    Images.DrawSizeGrip(Picture.Bitmap,0,0,CSkin.ColEtcBG,CSkin.ColEtcFrameGrip);
  end;
  GripImg.Refresh;

  SetShapeLblColor(CloseLbl,CloseShape,True);
  SetShapeLblColor(RefreshLbl,RefreshShape,True);
  SetShapeLblColor(VoteLbl,VoteShape,True);
  SetShapeLblColor(SortLbl,SortShape,True);
  SetShapeLblColor(MenuLbl,MenuShape,True);

  VotePanel.Color:=CSkin.dwEtcBG;

  SetCLst(MaxCountLst);
  SetLabel(TitleLbl);
  SetLabel(InfoLbl);

  with SeekGrid do begin
    FixedColor:=CSkin.dwEtcGridFixedBG;
    Color:=CSkin.dwEtcGridBG;
    Font.Color:=CSkin.dwEtcGridText;
  end;
  SeekGrid.Refresh;
end;

procedure TNetVote.FormCreate(Sender: TObject);
var
  cnt:integer;
begin
  AdjustWindowSize(Screen.Width,Screen.Height,MainINI.NetVotePos);
  with MainINI.NetVotePos do begin
    NetVote.Left:=Left;
    NetVote.Top:=Top;
    NetVote.Width:=Width;
    NetVote.Height:=Height;
  end;

  GS_NetVote:=TGridScroll.Create;
  GS_NetVote.LinkComponent(SeekGrid,SeekGridImg);

  with SeekGrid do begin
    SetGridRowCount(2);
    Cells[0,0]:='';
    Cells[1,0]:='';
    Cells[0,1]:='';
    Cells[1,1]:='';
  end;
  ReflectSeekGridFont;

  with NetVote.Constraints do begin
    MinHeight:=SeekGrid.Top+128;
    MaxHeight:=Screen.Height;
    MinWidth:=640;
    MaxWidth:=Screen.Width;
  end;

  PM_2lineComment.Checked:=MainINI.NetVoteView2lineComment;

  InfoLbl.Caption:='MDXOnline 投票ウィンドウ';
  NetVote.Visible:=True;

  with MaxCountLst do begin
    MaxCountChangeHold:=True;
    Clear;
    Items.Add('全て');
    for cnt:=1 to 20 do begin
      Items.Add(IntToStr(cnt*100)+'件まで');
    end;
    with MainINI do begin
      if Items.Count<(NetVoteMaxCountIndex+1) then NetVoteMaxCountIndex:=Items.Count-1;
      ItemIndex:=NetVoteMaxCountIndex;
    end;
    MaxCountChangeHold:=False;
  end;

  LoadSkin;
  
  FormResize(Sender);
  SizeChangeTimerTimer(Sender);

  if FileExists(Main.Network.CFG.VoteDataFilename)=True then DeleteFile(Main.Network.CFG.VoteDataFilename);

  VoteData.Loaded:=False;
end;

procedure TNetVote.FormDestroy(Sender: TObject);
begin
  GS_NetVote.Free;
end;

procedure TNetVote.ReflectSeekGridFont;
begin
  with SeekGrid do begin
    Font.Name:=MainINI.NetVoteViewFontName;
    Font.Size:=MainINI.NetVoteViewFontSize;
    Canvas.Font:=SeekGrid.Font;
    DefaultRowHeight:=(Canvas.TextHeight('0')+2)*3+4;
  end;
  SizeChangeTimer.Enabled:=True;
end;

procedure TNetVote.Init;
begin
  RefreshVoteTimer.Enabled:=True;
end;

procedure TNetVote.FormResize(Sender: TObject);
begin
  InfoLbl.Top:=NetVote.ClientHeight-InfoLbl.Height-4;
  GripImg.Top:=VotePanel.Height-4-GripImg.Height;
  GripImg.Left:=VotePanel.Width-4-GripImg.Width;
  SizeChangeTimer.Enabled:=True;
end;

procedure TNetVote.SizeChangeTimerTimer(Sender: TObject);
begin
  SizeChangeTimer.Enabled:=False;

  SeekGrid.Height:=NetVote.ClientHeight-SeekGrid.Top-8-InfoLbl.Height;

  InfoLbl.Width:=VotePanel.Width-4-InfoLbl.Left-GripImg.Width;

  with SeekGrid do begin
    Width:=NetVote.ClientWidth-GS_PartsSize-24;
    ColWidths[0]:=Canvas.TextWidth('000')+4;
    ColWidths[1]:=Width-ColWidths[0];
  end;

  GS_NetVote.ResetPosition;
end;

procedure TNetVote.RefreshVoteTimerTimer(Sender: TObject);
begin
  RefreshVoteTimer.Enabled:=False;
  RefreshVote;
  RefreshGrid;
  RefreshTitle;
end;

procedure TNetVote.RefreshVote;
var
  res:boolean;
begin
  InfoLbl.Caption:='投票ウィンドウを初期化しています…';

  if VoteData.Loaded=False then begin
    if FileExists(Main.Network.CFG.VoteDataFilename)=False then begin
      if Main.Network.NetworkEnable=False then exit;
      res:=Main.Network.GetHTTPDataFileSZip(Main.Network.CFG.VoteDataURL,Main.Network.CFG.VoteDataFilename,'ネットワーク投票データをダウンロードしています…');
      if res=False then begin
        ShowMessage('投票データの読み込みに失敗しました。');
        NetVote.Close;
        exit;
      end;
    end;
    LoadVoteData(Main.Network.CFG.VoteDataFilename,VoteData);
    VoteData.Loaded:=True;
  end;

  InfoLbl.Caption:='';
end;

procedure TNetVote.ClearGrid;
var
  x,y:integer;
begin
  with SeekGrid do begin
    for y:=1 to RowCount-1 do begin
      for x:=0 to ColCount-1 do begin
        Cells[x,y]:='';
      end;
    end;
    SetGridRowCount(2);
    Cells[0,0]:='idx';
    Cells[1,0]:='';
    Cells[0,1]:='';
    Cells[1,1]:='';
  end;
end;

procedure TNetVote.RefreshGrid;
var
  MaxCount:integer;
  cnt:integer;
  BackMaxCount:integer;
begin
  SizeChangeTimerTimer(nil);

  ClearGrid;

  with VoteData,SeekGrid do begin
    MaxCountChangeHold:=True;
    BackMaxCount:=MaxCountLst.ItemIndex;
    MaxCountLst.Items[0]:='全て('+IntToStr(VotesCount)+'件)';
    MaxCountLst.ItemIndex:=BackMaxCount;
    MaxCountChangeHold:=False;

    if VotesCount=0 then exit;
    if MaxCountLst.ItemIndex=0 then begin
      MaxCount:=VotesCount;
      end else begin
      MaxCount:=MaxCountLst.ItemIndex*100;
      if MaxCount>VotesCount then MaxCount:=VotesCount;
    end;
    SetGridRowCount(MaxCount+1);
    Cells[0,0]:='idx';
    Cells[1,0]:='';
    for cnt:=0 to MaxCount-1 do begin
      Cells[0,cnt+1]:=IntToStr((VotesCount-1)-cnt);
      Cells[1,cnt+1]:='';
    end;
  end;
end;

procedure TNetVote.RefreshTitle;
var
  cnt,Count:integer;
  Title:string;
  path,filename:string;
  Datafs:TFileStream;
begin
  if VoteData.VotesCount=0 then exit;

  Main.Network.NetworkCatalog.GetTitlePackStart(Datafs);

  Count:=SeekGrid.RowCount-1;

  with VoteData,SeekGrid do begin
    for cnt:=0 to Count-1 do begin
      if cnt<VotesCount then begin
        ExtractURL(Votes[cnt].Filename,path,filename);
        path:=copy(path,4,length(path));
        Title:=Main.Network.NetworkCatalog.GetTitlePackSeek(Datafs,path,filename,True);
        if Title='' then begin
          Votes[cnt].Title:='no title';
          end else begin
          Votes[cnt].Title:=Title;
        end;
        Cells[1,cnt+1]:='loaded';
      end;
    end;
  end;

  Main.Network.NetworkCatalog.GetTitlePackEnd(Datafs);

  InfoLbl.Caption:='';
end;

procedure TNetVote.SeekGridDblClick(Sender: TObject);
var
  idx:integer;
begin
  if SeekGrid.RowCount=0 then exit;

  idx:=strtointdef(SeekGrid.Cells[0,Grid_GetIndex(SeekGrid)],-1);
  if (idx<0) or (idx>=VoteData.VotesCount) then exit;

  with SeekGrid do begin
    MainFileCtl.ExecutePlayFile(VoteData.Votes[idx].Filename,True);
  end;
end;

procedure TNetVote.SeekGridKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key=VK_F11 then Key:=VK_ESCAPE;

  case Key of
    VK_ESCAPE: begin
      Key:=0;
      NetVote.Close;
    end;
    VK_RETURN: begin
      Key:=0;
      SeekGridDblClick(Sender);
    end;
  end;

  case Key of
    VK_END:   Grid_MoveIndex(SeekGrid,SeekGrid.RowCount-1);
    VK_HOME:  Grid_MoveIndex(SeekGrid,0);
    VK_PRIOR: Grid_MouseWheelWithCursor(SeekGrid,-1,Shift);
    VK_NEXT:  Grid_MouseWheelWithCursor(SeekGrid,1,Shift);
  end;

  if (Key=VK_END) or (Key=VK_HOME) or (Key=VK_PRIOR) or (Key=VK_NEXT) then begin
    Key:=0;
    Shift:=[];
    exit;
  end;
end;

procedure TNetVote.SeekEdtKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (Key=VK_ESCAPE) or (Key=VK_F11) or (Key=VK_RETURN) or (Key=VK_PRIOR) or (Key=VK_NEXT) or (Key=VK_UP) or (Key=VK_DOWN) or (Key=VK_HOME) or (Key=VK_END) then begin
    SeekGridKeyDown(Sender,Key,Shift);
    Key:=0;
  end;
end;

procedure TNetVote.InfoLblMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  MBarFlag:=True;
  MBarY:=Y;
end;

procedure TNetVote.InfoLblMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if MBarFlag=True then begin
    NetVote.Height:=NetVote.Height+(Y-MBarY);
  end;
end;

procedure TNetVote.InfoLblMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  MBarFlag:=False;
end;

procedure TNetVote.VotePanelMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  DlgDrag:=True;
  Dlgmx:=x;
  Dlgmy:=y;
end;

procedure TNetVote.VotePanelMouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
begin
  if DlgDrag=True then begin
    with NetVote do begin
      Left:=Left+(X-Dlgmx);
      Top:=Top+(Y-Dlgmy);
    end;
  end;
end;

procedure TNetVote.VotePanelMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  DlgDrag:=False;
end;

procedure TNetVote.CloseLblClick(Sender: TObject);
begin
  NetVote.Close;
end;

procedure TNetVote.SeekGridMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  col,row:integer;
begin
  SeekGrid.MouseToCell(x,y,col,row);

  if (col<1) or (row<1) then begin
    DlgDrag:=True;
    Dlgmx:=x;
    Dlgmy:=y;
  end;
end;

procedure TNetVote.SeekGridMouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
var
  col,row,idx:integer;
begin
  if DlgDrag=True then begin
    with NetVote do begin
      Left:=Left+(X-Dlgmx);
      Top:=Top+(Y-Dlgmy);
    end;
    end else begin
    if SeekGrid.RowCount=0 then exit;
    SeekGrid.MouseToCell(x,y,col,row);
    if row=-1 then exit;
    idx:=strtointdef(SeekGrid.Cells[0,row],-1);
    if (idx<0) or (idx>=VoteData.VotesCount) then begin
      InfoLbl.Caption:='';
      end else begin
      InfoLbl.Caption:=inttostr(idx)+' '+VoteData.Votes[idx].Comment;
    end;
  end;
end;

procedure TNetVote.SeekGridMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  DlgDrag:=False;
end;

procedure TNetVote.GripImgMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  MBarFlag:=True;
  MBarX:=X;
  MBarY:=Y;
end;

procedure TNetVote.GripImgMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if MBarFlag=True then begin
    NetVote.Width:=NetVote.Width+(X-MBarX);
    NetVote.Height:=NetVote.Height+(Y-MBarY);
  end;
end;

procedure TNetVote.GripImgMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  MBarFlag:=False;
end;

procedure TNetVote.RefreshLblClick(Sender: TObject);
begin
  VoteData.Loaded:=False;
  if FileExists(Main.Network.CFG.VoteDataFilename)=True then DeleteFile(Main.Network.CFG.VoteDataFilename);
  RefreshVoteTimer.Enabled:=True;
end;

procedure TNetVote.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  RefreshVoteTimer.Enabled:=False;
  ClearGrid;
end;

procedure TNetVote.MaxCountLstChange(Sender: TObject);
begin
  if MaxCountChangeHold=False then begin
    MainINI.NetVoteMaxCountIndex:=MaxCountLst.ItemIndex;
    RefreshVote;
  end;
end;

procedure TNetVote.SeekGridMouseWheelDown(Sender: TObject;
  Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
begin
  Handled:=True;
  Grid_MouseWheelViewOnly(SeekGrid,1,Shift);
end;

procedure TNetVote.SeekGridMouseWheelUp(Sender: TObject;
  Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
begin
  Handled:=True;
  Grid_MouseWheelViewOnly(SeekGrid,-1,Shift);
end;

procedure TNetVote.SeekGridDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  x,y:integer;
  Width,Height:integer;
  idx:integer;
  procedure DrawText(len:integer;msg:string);
  begin
    with SeekGrid.Canvas do begin
      if len<>-1 then begin
        TextRect(Bounds(x,y,Width*len,Height),x,y,msg);
        inc(x,Width*len);
        end else begin
        TextRect(Rect,x,y,msg);
      end;
    end;
  end;
  procedure DrawText2line(msg:string);
  var
    loop:boolean;
    p:integer;
    sb:boolean;
  begin
    if msg='' then exit;
    loop:=True;
    p:=1;
    while(loop=True) do begin
      if p>length(msg) then begin
        loop:=False;
        end else begin
        sb:=isAnkChar(byte(msg[p]));
        if sb=True then begin
          if (x+SeekGrid.Canvas.TextWidth(copy(msg,1,p)))>Rect.Right then begin
            loop:=False;
            end else begin
            inc(p);
          end;
          end else begin
          if (x+SeekGrid.Canvas.TextWidth(copy(msg,1,p+1)))>Rect.Right then begin
            loop:=False;
            end else begin
            inc(p,2);
          end;
        end;
      end;
    end;
    with SeekGrid.Canvas do begin
      if p>=2 then TextRect(Rect,x,y,copy(msg,1,p-1));
      TextRect(Rect,x,y+Height,copy(msg,p,255));
    end;
  end;
begin
  if Application.Title='MDXClose' then exit;

  with SeekGrid.Canvas do begin
    Brush.Style:=bsSolid;
    if (gdSelected in State) then begin
      Brush.Color:=CSkin.dwEtcGridSelectBG;
      end else begin
      if (gdFixed in State) then begin
        Brush.Color:=CSkin.dwEtcGridFixedBG;
        end else begin
        Brush.Color:=CSkin.dwEtcGridBG;
      end;
    end;
    FillRect(Rect);

    Brush.Style:=bsClear;
    Font.Color:=CSkin.dwEtcGridText;
    Width:=TextWidth('0');
    Height:=TextHeight('0')+2;

    if ACol=0 then begin
      x:=Rect.Left+2;
      y:=Rect.Top+1+(Height*1);
      TextRect(Rect,x,y,SeekGrid.Cells[ACol,ARow]);
      end else begin
      if (ARow<=0) then begin
        x:=Rect.Left+2;
        y:=Rect.Top+2+(Height*0);
        DrawText(16,'投票者名');
        DrawText(10,'投票日時');
        DrawText(9,'お勧め度');
        DrawText(7,'知名度');
        if MainINI.NetVoteView2lineComment=False then begin
          DrawText(-1,'コメント');
          end else begin
          DrawText(-1,'コメント1');
        end;

        x:=Rect.Left+2;
        y:=Rect.Top+2+(Height*1);
        if MainINI.NetVoteView2lineComment=False then begin
          DrawText(-1,'ファイル名');
          end else begin
          DrawText(42,'ファイル名');
          DrawText(-1,'コメント2');
        end;

        x:=Rect.Left+2;
        y:=Rect.Top+2+(Height*2);
        DrawText(-1,'タイトル');
        end else begin
        idx:=strtointdef(SeekGrid.Cells[0,ARow],-1);
        if (idx<0) or (VoteData.VotesCount<=idx) then begin
          end else begin
          with VoteData.Votes[idx] do begin
            x:=Rect.Left+2;
            y:=Rect.Top+2+(Height*0);
            DrawText(16,Name);
            DrawText(10,FormatDateTime('mmdd/hhnn',Date));
            DrawText(4,inttostr(Rating));
            DrawText(4,inttostr(Celebrity));
            if MainINI.NetVoteView2lineComment=False then begin
              DrawText(-1,Comment);
              end else begin
              DrawText2line(Comment);
            end;

            x:=Rect.Left+2;
            y:=Rect.Top+2+(Height*1);
            if MainINI.NetVoteView2lineComment=False then begin
              DrawText(-1,copy(Filename,4,length(Filename)));
              end else begin
              TextRect(Bounds(x,y,Width*33,Height),x,y,copy(Filename,4,length(Filename)));
            end;

            x:=Rect.Left+2;
            y:=Rect.Top+2+(Height*2);
            DrawText(-1,Title);
          end;
        end;
      end;
    end;

  end;
end;

procedure TNetVote.SortLblClick(Sender: TObject);
begin
  ShowMessage('ソート機能はまだ実装されていません。');
end;

procedure TNetVote.VoteLblClick(Sender: TObject);
var
  Vote:TVote;
  RetryFlag:boolean;
  function ProcessVoteOverride(Vote:TVote):boolean;
  begin
    while (0=0) do begin
      if ProcessVote(Vote)=True then begin
        Result:=True;
        exit;
        end else begin
        if MessageDlg('投票に失敗しました。再試行しますか？',mtConfirmation,[mbYes,mbNo],0)=mrNo then begin
          Result:=False;
          exit;
        end;
      end;
    end;
  end;
begin
  if Main.gFileInfo.GetFullPath='' then begin
    ShowMessage('最後に再生した曲が対象となりますので、'+CRLF+'先に曲を再生してから再度投票してください。');
    exit;
  end;

  if Main.gFileInfo.isNetworkMode=False then begin
    ShowMessage('MDXOnline上のファイル以外は投票できません。');
    exit;
  end;

  with Vote do begin
    Name:=MainINI.NetVoteLastName;
    MailAddress:='';
    Comment:='';
    Date:=now;
    Rating:=MainINI.NetVoteLastRating;
    Celebrity:=MainINI.NetVoteLastCelebrity;
    Genre:=MainINI.NetVoteLastGenre;
    Filename:=Main.gFileInfo.GetFullPath;
    Title:=Main.gFileInfo.GetCompactTitle;
  end;

  Application.CreateForm(TSetVote, SetVote);
  RetryFlag:=True;
  while (RetryFlag=True) do begin
    SetVote.SetCreate(Vote);
    if SetVote.ShowModal<>mrOK then begin
      RetryFlag:=False;
      end else begin
      Vote:=SetVote.Vote;
      with Vote do begin
        MainINI.NetVoteLastName:=Name;
        MainINI.NetVoteLastRating:=Rating;
        MainINI.NetVoteLastCelebrity:=Celebrity;
        MainINI.NetVoteLastGenre:=Genre;
      end;
      if ProcessVoteOverride(Vote)=True then begin
        InfoLbl.Caption:='投票が正常に完了しました。リストを更新します。';
        ShowMessage(InfoLbl.Caption);
        RefreshLblClick(nil);
        RetryFlag:=False;
      end;
    end;
  end;
  SetVote.Release;
end;

function TNetVote.ProcessVote(Vote:TVote):boolean;
var
  IdHTTP:TIdHTTP;
  res:string;
  BreakFlag:boolean;
  URL:string;
  procedure SetHTTPParams(_Host:string;_Port:integer;_URL:string);
  begin
    with IdHTTP do begin
      AllowCookies:=False;
      ASCIIFilter:=False;
      HandleRedirects:=False;
      Host:=_Host;
      Port:=_Port;
      ProtocolVersion:=pv1_0;
      ReadTimeout:=15*1000;
      RecvBufferSize:=8192;
      SendBufferSize:=8192;

      ProxyParams.ProxyPort:=0;
      ProxyParams.ProxyServer:='';

      Request.Host:=_Host;
      Request.URL:=_URL;
    end;
  end;
begin
  Result:=False;

  URL:=Main.Network.CFG.VoteSendURL+'?'+GetEncordVote(Vote);

  IdHTTP:=nil;
  BreakFlag:=False;
  try
    IdHTTP:=TIdHTTP.Create(nil);
    IdHTTP.OnStatus:=ProcessVoteOnStatus;
    SetHTTPParams(Main.Network.CFG.Host,Main.Network.CFG.Port,URL);
    res:=IdHTTP.Get(IdHTTP.Request.URL);
    except else begin
      InfoLbl.Caption:='未定義ネットワークエラーが発生したため投票できませんでした。'+CRLF+'しばらくしてから再試行してください。';
      ShowMessage(InfoLbl.Caption);
      BreakFlag:=True;
    end;
  end;
  IdHTTP.Free;
  if BreakFlag=True then exit;

  if res<>'voteok' then begin
    InfoLbl.Caption:='エラーが発生したため投票できませんでした。'+CRLF+'応答:'+res;
    ShowMessage(InfoLbl.Caption);
    exit;
  end;

  Result:=True;
end;

procedure TNetVote.ProcessVoteOnStatus(ASender: TObject; const AStatus: TIdStatus; const AStatusText: String);
begin
  InfoLbl.Caption:='HTTPStatus:'+AStatusText;
end;

procedure TNetVote.ExtractURL(const url:string;var path,filename:string);
var
  cnt:integer;
  p:integer;
begin
  p:=-1;
  for cnt:=1 to Length(url) do begin
    if url[cnt]='\' then p:=cnt;
  end;
  if p=-1 then begin
    path:='';
    filename:='';
    end else begin
    path:=copy(url,1,p);
    filename:=copy(url,p+1,255);
  end;
end;

procedure TNetVote.MenuLblClick(Sender: TObject);
var
  pos:TPoint;
begin
  GetCursorPos(pos);
  PopupMenu.Popup(pos.X,pos.Y);
end;

procedure TNetVote.PM_2lineCommentClick(Sender: TObject);
begin
  MainINI.NetVoteView2lineComment:=not MainINI.NetVoteView2lineComment;
  PM_2lineComment.Checked:=MainINI.NetVoteView2lineComment;
  SeekGrid.Refresh;
end;

procedure TNetVote.PM_ListFontClick(Sender: TObject);
begin
  with FontDlg do begin
    Font.Name:=MainINI.NetVoteViewFontName;
    Font.Size:=MainINI.NetVoteViewFontSize;
    MaxFontSize:=0;
    MinFontSize:=0;
    if Execute=True then begin
      MainINI.NetVoteViewFontName:=Font.Name;
      MainINI.NetVoteViewFontSize:=Font.Size;
      ReflectSeekGridFont;
    end;
  end;
end;

procedure TNetVote.SetGridRowCount(cnt:integer);
begin
  SeekGrid.RowCount:=cnt;
  GS_NetVote.ResetPosition;
  SizeChangeTimer.Enabled:=True;
end;

end.
