program Paster;
//{$DEFINE DEV}
const
  HOSTDef = 'paste.villavu.com';
  
function GetName: string;
begin;
  Result := 'Paster';
end;

function GetVersion: string;
begin;
  Result := '0.4a';
end;

{$IFDEF EXTENSION}

var
  Paster_Menu, GetPaste_MenuItem, Private_MenuItem,
  Browser_MenuItem, Paster_MenuItem, AltHost_Menu: TMenuItem;
  Divider_MenuItems: array[1..2] of TMenuItem;
  AltHost_Menus: array[1..5] of TMenuItem;
  AltHost_MenuItems: array[1..5] of array[1..5] of TMenuItem;

function EncodeString(Data: string): string;
var
  Pattern, Replacement: TStringArray;
  I: integer;
begin
  Pattern     := ['\',   #8,   #9,  #10,  #11,  #12,  #13,  '"',   {#39,}   '/'];
  Replacement := ['\\', '\b', '\t', '\n', '\v', '\f', '\r', '\"', {'\'#39,} '\/'];
  Result := Data;
  if (Length(Pattern) = Length(Replacement)) then
    for I := Low(Pattern) to High(Pattern) do
      Result := Replace(Result, Pattern[I], Replacement[I], [rfIgnoreCase, rfReplaceAll]);
end;

function JSONRequest(var Data: string; const HOST, Method: string): boolean;
begin
  {$IFDEF DEV}WriteLn('JSONRequest('#39 + Data + #39', '#39 + HOST + #39', '#39 + Method + #39');');{$ENDIF}
  Data := GetPageEx('http://' + HOST + '/json/?method=' + Method, Data, 'application/json');
  {$IFDEF DEV}WriteLn('Data := '#39 + Data + #39';');{$ENDIF}
  if (Data = '') then
  begin
    Data := '{"data": null, "error": "Server unresponsive!"}';
    Result := False;
    Exit;
  end;

  if (not ((Data[1] = '{') and (Data[Length(Data) - 1] = '}'))) then
  begin
    Data := '{"data": null, "error": "Host \"' + HOST + '\" is not a LodgeIt Server!"}';
    Result := False;
    Exit;
  end;

  if (Method = 'pastes.getPaste') then
  begin
    //Little hack for getPaste too work....
    Data := Replace(Data, '{"data": {', '{', []);
    Data := Replace(Data, '}, "error": ', ', "error": ', []);
  end;

  Result := True;
end;

function GetPaste(HOST: string): boolean;
var
  Data: string;
begin
  if (HOST = '') then
    HOST := HOSTDef;
  if (InputQuery(GetName + ' ' + GetVersion + ' Extension', 'Which ID would you like to grab?', Data)) then
  begin
    if IntToStr(StrToInt(Data)) = Data then
      Data := '{"paste_id": ' + Data + '}'
    else
      Data := '{"paste_id": "' + Data + '"}';

    if (not (JSONRequest(Data, HOST, 'pastes.getPaste'))) then
    begin
      WriteLn('[Paster]Error: ' + GetJSONValue(Data, 'error'));
      Result := False;
      Exit;
    end;

    if ((GetJSONValue(Data, 'data') = 'null') and (GetJSONValue(Data, 'error') = 'null')) then
    begin
      WriteLn('[Paster]Error: Invalid Paste ID!');
      Result := False;
      Exit;
    end;

    WriteLn('Opening Paste #' + GetJSONValue(Data, 'paste_id') + ' in a new tab!');
    OpenScript('Paste #' + GetJSONValue(Data, 'paste_id'), GetJSONValue(Data, 'code'), False);
    Result := True;
  end;
end;

function PasteIt(out Data: string; HOST: string): boolean;
var
  ScriptTextEx: string;
begin
  if (MessageDlg(GetName + ' ' + GetVersion + ' Extension', 'Upload this script to ' + HOST + '?', mtConfirmation, [mbYes, mbNo], 0) = mrYes) then
  begin
    ScriptTextEx := ScriptText;

    if (ExecRegExpr('([N|n][A|a][M|m][E|e]|[P|p][A|a][S|s]{2}|[P|p][I|i][N|n])', ScriptTextEx)) then
      if (MessageDlg(GetName + ' ' + GetVersion + ' Extension', 'Would you like to mask sensitive data?', mtConfirmation, [mbYes, mbNo], 0) = mrYes) then
        ScriptTextEx := ReplaceRegExpr('([N|n][A|a][M|m][E|e]|[P|p][A|a][S|s]{2}|[P|p][I|i][N|n])\s*\:\=\s*\''.*?\'';', ScriptTextEx, '$1 := ''*********'';', True);

    Data := '{"language": "delphi", "code": "' + EncodeString(ScriptTextEx) + '", "private": ' + Lowercase(BoolToStr(Private_MenuItem.Checked)) + '}';
    JSONRequest(Data, HOST, 'pastes.newPaste');
    if (GetJSONValue(Data, 'error') = 'null') then
    begin
      Data := GetJSONValue(Data, 'data');
      Result := True;
    end else
      Data := '[Paster]Error: ' + GetJSONValue(Data, 'error');
  end;
end;

procedure Paste(Host: string);
var
  Data: string;
begin
  if (HOST = '') then
    HOST := HOSTDef;
  if PasteIt(Data, Host) then
  begin
    if (Browser_MenuItem.Checked) then
    begin
      WriteLn('Opening pasted script at "http://' + HOST + '/show/' + Data + '/"!');
      OpenWebPage('http://' + HOST + '/show/' + Data + '/');
    end else
      WriteLn('Script pasted at id "' + Data + '"');
  end else
    WriteLn(Data);
end;

procedure UpdateDefault(I: integer);
var
  J: integer;
begin
  Settings.setKeyValue('DefaultHost', IntToStr(I));
  for J := 1 to 5 do
    if (J = I) then
      AltHost_MenuItems[J][4].Checked := True
    else
      AltHost_MenuItems[J][4].Checked := False;
end;

procedure UpdateHost(I: integer);
var
  Data: string;
begin
  if InputQuery(GetName + ' ' + GetVersion + ' Extension', 'Please input the LodgeIt Host! (Ex: paste.pocoo.org)', Data) then
  begin
    {$IFDEF DEV}WriteLn('Data := '#39 + Data + #39';');{$ENDIF}
    if (Data = '') then
      if (AltHost_Menus[I].Caption = 'Host ' + IntToStr(I)) then
      begin
        WriteLn('[Paster]Error: The host cannot be blank!');
        Exit;
      end else
      begin
        AltHost_Menus[I].Caption := 'Host ' + IntToStr(I);
        AltHost_MenuItems[I][1].Enabled := False;
        AltHost_MenuItems[I][2].Enabled := False;
        AltHost_MenuItems[I][4].Enabled := False;
        Settings.setKeyValue('Host' + IntToStr(I), 'Host ' + IntToStr(I));
        if (Settings.getKeyValueDef('DefaultHost', '1') = IntToStr(I)) then
          UpdateDefault(1);
        Exit;
      end;
    AltHost_Menus[I].Caption := Data;
    AltHost_MenuItems[I][1].Enabled := True;
    AltHost_MenuItems[I][2].Enabled := True;
    AltHost_MenuItems[I][4].Enabled := True;
    Settings.setKeyValue('Host' + IntToStr(I), Data);
  end;
end;

procedure OnClick(Sender: TObject);
var
  I, K: integer;
begin;
  {$IFDEF DEV}
  if (Sender is TMenuItem) then
    WriteLn('Sender is '#39 + TMenuItem(Sender).Name + #39'.'); //(Sender as TMenuItem).Name
  {$ENDIF}
  case Sender of
    Paster_MenuItem: Paste(Settings.getKeyValue('Host' + Settings.getKeyValueDef('DefaultHost', '1')));
    GetPaste_MenuItem: GetPaste(Settings.getKeyValue('Host' + Settings.getKeyValueDef('DefaultHost', '1')));
    Private_MenuItem: begin
        Private_MenuItem.Checked := (not (Private_MenuItem.Checked));
        Settings.setKeyValue('Private', Lowercase(BoolToStr(Private_MenuItem.Checked)));
        {$IFDEF DEV}WriteLn('Private = ' + Lowercase(BoolToStr(Private_MenuItem.Checked)));{$ENDIF}
      end;
    Browser_MenuItem: begin
        Browser_MenuItem.Checked := (not (Browser_MenuItem.Checked));
        Settings.setKeyValue('OpenBrowser', Lowercase(BoolToStr(Browser_MenuItem.Checked)));
        {$IFDEF DEV}WriteLn('OpenBrowser = ' + Lowercase(BoolToStr(Browser_MenuItem.Checked)));{$ENDIF}
      end;
  end;
  for I := 1 to 5 do
    for K := 1 to 5 do
      if (Sender = AltHost_MenuItems[I][K]) then
      begin
        case K of
          1: Paste(Settings.getKeyValue('Host' + IntToStr(I)));
          2: GetPaste(Settings.getKeyValue('Host' + IntToStr(I)));
          4: UpdateDefault(I);
          5: UpdateHost(I);
        end;
        Break;
      end;
end;

procedure Attach;
begin;
  WriteLn(GetName + ' v' + GetVersion + ' by Dgby714 Loaded!');
  Paster_Menu.Visible := True;
end;

procedure Detach;
begin
  Paster_Menu.Visible := False;
end;

procedure Free;
{var
  I, K: integer;}
begin
  {for I := 5 downto 1 do
  begin
    for K := 5 downto 1 do
      AltHost_MenuItems[I][K].Free;
    AltHost_Menus[I].Free;
  end;
  AltHost_Menu.Free;
  Private_MenuItem.Free;
  for I := 2 downto 1 do
    Divider_MenuItems[I].Free;
  Paster_MenuItem.Free;
  Paster_Menu.Free;}
end;

procedure init;
var
  I, K: integer;
begin;
  Paster_Menu := TMenuItem.Create(Simba_MainMenu);
  Paster_Menu.Caption := GetName;
  Simba_MainMenu.Items.Add(Paster_Menu);
  
  Paster_MenuItem := TMenuItem.Create(Paster_Menu);
  with Paster_MenuItem do
  begin
    Name := 'Default_Paste';
    Caption := 'Paste It!';
    OnClick := @OnClick;
  end;
  Paster_Menu.Add(Paster_MenuItem);

  GetPaste_MenuItem := TMenuItem.Create(Paster_Menu);
  with GetPaste_MenuItem do
  begin
    Name := 'Default_GetPaste';
    Caption := 'Get Paste!';
    OnClick := @OnClick;
  end;
  Paster_Menu.Add(GetPaste_MenuItem);

  for I := 1 to 2 do
  begin
    Divider_MenuItems[I] := TMenuItem.Create(Paster_Menu);
    Divider_MenuItems[I].Caption := '-';
  end;

  Paster_Menu.Add(Divider_MenuItems[1]);

  Private_MenuItem := TMenuItem.Create(Paster_Menu);
  with Private_MenuItem do
  begin
    Name := 'Private_Setting';
    Caption := 'Private';
    OnClick := @OnClick;
    Checked := (Lowercase(Settings.getKeyValueDef('Private', 'true')) = 'true');
  end;
  Paster_Menu.Add(Private_MenuItem);

  Browser_MenuItem := TMenuItem.Create(Paster_Menu);
  with Browser_MenuItem do
  begin
    Name := 'Browser_Setting';
    Caption := 'Open in Browser';
    OnClick := @OnClick;
    Checked := (Lowercase(Settings.getKeyValueDef('OpenBrowser', 'true')) = 'true');
  end;
  Paster_Menu.Add(Browser_MenuItem);

  Paster_Menu.Add(Divider_MenuItems[2]);
  
  AltHost_Menu := TMenuItem.Create(Paster_Menu);
  AltHost_Menu.Caption := 'Hosts';
  Paster_Menu.Add(AltHost_Menu);
  
  for I := 1 to 5 do
  begin
    AltHost_Menus[I] := TMenuItem.Create(AltHost_Menu);
    if (I = 1) then
      AltHost_Menus[I].Caption := HOSTDef
    else
      AltHost_Menus[I].Caption := Settings.getKeyValueDef('Host' + IntToStr(I), 'Host ' + IntToStr(I));
    AltHost_Menu.Add(AltHost_Menus[I]);
	
    for K := 1 to 5 do
    begin
      AltHost_MenuItems[I][K] := TMenuItem.Create(AltHost_Menus[I]);
      case K of
        1: begin
            AltHost_MenuItems[I][1].Name := 'Host' + IntToStr(I) + '_Paste';
            AltHost_MenuItems[I][1].Caption := 'Paste It!';
          end;
        2: begin
            AltHost_MenuItems[I][2].Name := 'Host' + IntToStr(I) + '_GetPaste';
            AltHost_MenuItems[I][2].Caption := 'Get Paste!';
          end;
        3: AltHost_MenuItems[I][3].Caption := '-';
        4: begin
            AltHost_MenuItems[I][4].Name := 'Host' + IntToStr(I) + '_Default';
            AltHost_MenuItems[I][4].Caption := 'Default';
            AltHost_MenuItems[I][4].Checked := (Settings.getKeyValueDef('DefaultHost', '1') = IntToStr(I));
          end;
        5: begin
            AltHost_MenuItems[I][5].Name := 'Host' + IntToStr(I) + '_Update';
            AltHost_MenuItems[I][5].Caption := 'Update Host';
          end;
      end;
      AltHost_MenuItems[I][K].OnClick := @OnClick;
      if ((not ((K = 3) or (K = 5))) and (AltHost_Menus[I].Caption = 'Host ' + IntToStr(I))) then
        AltHost_MenuItems[I][K].Enabled := False;
      if ((I = 1) and (K = 5)) then
        AltHost_MenuItems[I][K].Visible := False;
      AltHost_Menus[I].Add(AltHost_MenuItems[I][K]);
    end;
  end;
end;
{$ENDIF}

begin
{$IFNDEF EXTENSION}
  MessageDlg(GetName + ' v' + GetVersion + ' by Dgby714!',
  'This is a Extension for Simba.'#13#10
  'If you are in Simba click View->Extensions and enable paster.sex!',
  mtWarning, [mbOK]);
{$ENDIF}
end.

