with String_Utilities;
with Simple_Text_Io;
procedure Format_Solution (Input_Filename : String; Output_Filename : String) is

    package Sio renames Simple_Text_Io;

    type State is (None, If_Found, Elsif_Found);

    Current_State : State := None;

    Left_Margin : Positive;

    Input : Sio.File_Type;
    Output : Sio.File_Type;

    function Last_Fragment_Is_In_Quotes
                (Fragment : String; Line : String) return Boolean is

        Last_Quote_Position : Natural :=
           String_Utilities.Reverse_Locate ("""", Line);

        Next_To_Last_Quote_Position : Natural :=
           String_Utilities.Reverse_Locate
              ("""", (Line (Line'First .. Last_Quote_Position - 1)));

        Last_Fragment_Position : Natural :=
           String_Utilities.Reverse_Locate (Fragment, Line);
    begin
        if Last_Quote_Position = 0 or Last_Fragment_Position = 0 then
            return False;
        elsif Last_Fragment_Position < Last_Quote_Position and then
              Last_Fragment_Position > Next_To_Last_Quote_Position then
            return True;
        else
            return False;
        end if;

    end Last_Fragment_Is_In_Quotes;

    function Begins_With (Fragment : String; Line : String) return Boolean is
    begin
        if Fragment'Length > Line'Length then
            return False;
        else
            return String_Utilities.Equal
                      (Fragment, Line (Line'First ..
                                          Line'First + Fragment'Length - 1));
        end if;
    end Begins_With;

    function Ends_With (Fragment : String; Line : String) return Boolean is
    begin
        if Fragment'Length > Line'Length then
            return False;
        else
            return String_Utilities.Equal
                      (Fragment, Line (Line'Last - Fragment'Length + 1 ..
                                          Line'Last));
        end if;
    end Ends_With;

    function Contains (Fragment : String; Line : String) return Boolean is
    begin
        if Fragment'Length > Line'Length then
            return False;
        else
            return not (String_Utilities.Locate (Fragment, Line) = 0);
        end if;
    end Contains;

    procedure Put_Then_Line (File : Sio.File_Type; Margin : Natural) is
    begin
        for I in 1 .. Margin - 1 loop
            Sio.Put (File, ' ');
        end loop;
        Sio.Put_Line (File, "then");
    end Put_Then_Line;

begin
    Sio.Open (Input, Sio.In_File, Input_Filename);
    Sio.Create (Output, Sio.Out_File, Output_Filename);

    while not Sio.End_Of_File (Input) loop
        declare
            Line : constant String := Sio.Get_Line (Input);
            Stripped_Line : constant String := String_Utilities.Strip (Line);
        begin
            loop
                case Current_State is

                    when None =>

                        if Begins_With ("if ", Stripped_Line) then

                            Current_State := If_Found;

                            Left_Margin := String_Utilities.Locate
                                              ("if ", Line) - Line'First + 1;

                        elsif Begins_With ("elsif ", Stripped_Line) then

                            Current_State := Elsif_Found;

                            Left_Margin := String_Utilities.Locate
                                              ("elsif ", Line) - Line'First + 1;
                        else

                            Sio.Put_Line (Output, Line);
                            exit;
                        end if;


                    when If_Found | Elsif_Found =>

                        if Ends_With (" then", Stripped_Line) and then
                           not Ends_With ("and then", Stripped_Line) then


                            if Contains ("--", Stripped_Line) then
                                if Last_Fragment_Is_In_Quotes
                                      ("--", Stripped_Line) then
                                    Sio.Put_Line (Output,
                                                  Line (Line'First ..
                                                           Line'Last - 4));

                                    Put_Then_Line (Output, Left_Margin);
                                    Current_State := None;
                                else
                                    Sio.Put_Line (Output, Line);
                                end if;
                            else
                                Sio.Put_Line (Output, Line (Line'First ..
                                                               Line'Last - 4));

                                Put_Then_Line (Output, Left_Margin);
                                Current_State := None;
                            end if;
                        elsif String_Utilities.Equal
                                 ("then", Stripped_Line) then

                            Put_Then_Line (Output, Left_Margin);
                            Current_State := None;
                        else
                            Sio.Put_Line (Output, Line);
                        end if;
                        exit;
                end case;
            end loop;
        end;
    end loop;

    Sio.Close (Input);
    Sio.Close (Output);
end Format_Solution;