// kate: space-indent on; indent-width 3; replace-tabs on; remove-trailing-spaces all;
// kate: syntax pascal; indent-mode pascal;

(**********************************************   // check: indent OK?
         *                                            *
    *       Commment to test alignment           *
           *                                            *
  *                                            *
         **********************************************)

 (*************************************************************************
 Another Comment

 Relative alignment should be kept ...
       After indent, first character of this line should 
       still remain under the 'v' in relative

 *************************************************************************)

	program fred;

	uses bbb;

	label fred001;
	var   i: integer;

	const const0 = 0;
c33 = 12;
const1 = 17;
const2 = 18.4;

	type x = record a: real; c : char end;

   // r = record ... vs unfinished typedef
rType = record  // cr here ==> type def
a: aType;       // this can be realigned manually
b: bType;       // should follow line above
c: cType
end;

                  colourType = 
                     { unfinished type declaration }
                     ( red,    // CHECK: everything should line up below this
                                          orange, // this must follow line above
                                                   green,
                                                   blue,
                                                   indigo,
                                                   yellow,
                                                   violet
                                                   // CHECK: the comments should line up as well
                                                   // closing paren should align to list when it's left shifted
                                                   //                            to opening paren otherwise
                                                );

            otherTypeDef = integer;

// CHECK: next line should keep its relative alignment
         {next}
            ant = RECORD CASE F: BOOLEAN OF
TRUE: ( fred : REAL;
joe  : INTEGER;
);  // parens should line up
FALSE: (  ted : ARRAY[
1..16
] OF BOOLEAN;
moe: CHAR;
        );
                                    END; // 'case' + 'record' share same 'end'



                        var a: real;

RW:  ARRAY [AASY..ZZSY]
OF   (*RESERVED WORDS*)   PACKED ARRAY [1..RWLENGTH,
2..66 ]     // CHECK: this line should be indented
OF CHAR;    // CHECK: this line should be indented from array

                           RW:  ARRAY [AASY..ZZSY] OF   (*RESERVED WORDS*)
                                 PACKED ARRAY [1..RWLENGTH] OF CHAR;

                        var
                           sym : keysymbol;
                           pos : hashIndex;
                           len : charLenType;


                        type tR = record
                                     i: integer;   // CHECK: can be aligned manually, but default indented from record
                                    r: real;      // should align with line immediately above
                                    a: array[1..11] of char;

                                       case boolean of
                                          true: ( fred : real;
                                                   joe  : integer;
                                                );  // parens should line up
                                          false: (  ted : array[
                                                                  1..16
                                                               ] of boolean;
                                                   moe: char;
                                                );
                                    end; // 'case' + 'record' share same 'end'

                              tArray = array[0..17] of real; // should indent wrt 'type'

                           type    colourType = (
                                         red,    // CHECK: this line can be adjusted manually
                                                   orange, // this must follow line above
                                                   green,
                                                   blue,
                                                   indigo,
                                                   yellow,
                                                   violet
                                                   // CHECK: the comments should line up as well
                                                   // closing paren should align to list when it's left shifted
                                                   //                            to opening paren otherwise
                                                );

                     blah = char;  // should align after type

                     optionset = set of options;

                  var
                     r1: record
                            i:    integer;
r:    real;                   // should line up with first member
a:    array[0..7] of char;
end;  // CHECK: end is outdented relative to first member

optionset : set of options;

                  options : (    crsupp,crbefore,blinbefore,
                                 dindonkey,dindent,spbef,
                                 spaft,gobsym,
                                 inbytab,   { indent current margin (was indent from symbol pos) }
                                 crafter,
                                 finl            { force symbol to follow on same line as previous symbol }
                            );

optionset = set of options;

aa: array[   1..9, // should be indented after cr
3..22 ]
          of ( crsupp,crbefore,blinbefore,
                dindonkey,dindent,spbef,
                  spaft,gobsym,
                  inbytab,   { indent current margin (was indent from symbol pos) }
                  crafter,
                  finl            { force symbol to follow on same line as previous symbol }
               );

aaa: array[ 1..3,
            4..5,
            12..11 ]
 of record // cr after here should indent from record
 a: array[1..6] of char;
 i: integer;
end;

 { CHECK: following text should keep indent relative to open/close brace
          when annotating, behavior of "external", "end" and possibly other keywords
          depends on whether we are in procedure declaration,
          item (var/const/type) declaration, or statements
          }


   procedure AVeryVeryLongFunctionName(const A : tRealArrayType;
                                       N : tIntegerType;
                                       var H : tRealArrayType); forward;

   (*************************************************************************
   CHECK:   comment is correctly aligned with precedinging statement

   Input parameters:
   A       -   description

   N       -   longer description, but
               still preserving relative format

   Output parameters:
   H       - other meaningful description

   Result:
      True, if successful
      False, otherwise
   *************************************************************************)

     var size : (small, medium, large);	
fred : real;

var   r : record i: integer; c: char end;

   a: array[ 1..9,    // should be indented after var
             'a'..'z'        // non-code, should line up with opening arg
           ] of integer;

        begin (* AVeryVeryLongFunctionName *)

if a then begin
s1;
             16:   f(32);  //CHECK: label forced to margin, statement is on new line with comment
end;

for i := 0 to 100 do
begin
with p^ do
begin s1; s2; s3 end
end;

with p^ do
begin s1; s2; s3 end;

                        for i := firstCh to lastCh do chtype[chr(i)] := none;
                        value['0'] := 0; value['1'] := 1; value['2'] := 2;
                        value['3'] := 3; value['4'] := 4; value['5'] := 5;
                        value['6'] := 6; value['7'] := 7; value['8'] := 8;
                        value['9'] := 9;
                        value['A'] := 10; value['B'] := 11; value['C'] := 12;
                        value['D'] := 13; value['E'] := 14; value['F'] := 15;
                        value['a'] := 10; value['b'] := 11; value['c'] := 12;
                        value['d'] := 13; value['e'] := 14; value['f'] := 15;
 
IF NOT (CH IN ['{','}']) THEN
// comment
BEGIN  IF CH <= 'Z' THEN CMDCH := CH ELSE CMDCH := CHR(ORD(CH)-ORD('a')+ORD('A') );
NEXTCH;
IF CMDCH = 'L' THEN
COMMAND(LISTON)
ELSE IF CMDCH = 'T' THEN
COMMAND(TRACEON)
ELSE IF CMDCH = 'I' THEN
COMMAND(INCLUDE)
ELSE IF CMDCH = 'Z' THEN
REPEAT
BEGIN
www.fred.com;
REPEAT commandIn UNTIL numRem = 0;
s1;
s2;
END;
UNTIL False
ELSE IF CMDCH = 'Q' THEN begin
COMMAND(QUIET)
end ELSE IF CMDCH = 'V' THEN
COMMAND(VERBOSE)
else if COMMAND.STRVAL = 'unknown' then
begin
IF
(numStr[0] >= 0) AND
(numStr[1] IN ['+', '-', '0' .. '9', '?']) // CHECK: indent
THEN
Power.Supply := '"AC' ELSE Power.Supply := '"DC'
end else  if CommandResult.Str = 'helpIamLost' then begin
Power.Supply := SetPowerSupplyCommands(Plus15V.Increase(Amps));
end else if (line = 'SHORT') OR (line = 'OPEN') THEN  BEGIN
OpenCircuit;
{*smoke billows out*}
IF SPARKS THEN
BEGIN
SPARKS := FALSE;
ShutDown
END
END ELSE IF
(line = 'OPEN') OR (line = 'CLOSED') THEN
BEGIN;
AddFuse(Low);
IF SPARKS THEN
BEGIN;
SPARKS := False;
CircuitBreaker(wishfulThinking)
END else if cond then
statement;
END ELSE IF (line = 'PLUS') OR (line = 'MINUS') THEN Transform(RedPhase)
ELSE IF (line = 'RED') OR (line = 'BLACK') THEN Transform(BluePhase)
ELSE IF line = 'XX' THEN Transistor
ELSE IF line = 'YYYY' THEN SetCurrent(FiveAmps)
ELSE IF line = 'QQQQ' THEN SetPower(FiveWatts)
ELSE IF line = 'AAAAA' THEN Power(FiveAmps)
ELSE IF
   {* QWERTY COMMENT LLLLLLLLL ####### *}
   line = 'SSSSS' THEN
BEGIN
actualphase := YellowPhase;
AdjustLinePhase(NewPhase);
END
ELSE IF
line = 'Noisy' THEN Filter
ELSE IF line = 'BLUE' THEN
BEGIN
AdjustLinePhase(XPhase);
Erase := True
END ELSE IF
line = 'RED' THEN BEGIN Swap; Hope END
ELSE IF
   line = '415' THEN iNumPut415
ELSE IF
   // a statement like this has no chance of being correctly indented ...
   // otoh, it shouldn't turn out catastrophically wrong.
   line = 'REFL' THEN FOR i := 1 TO numLines DO
WriteLn('level=', powerLevel[i], ' ', name[i]+'='+power[i])
ELSE IF
   line = 'HIGH' THEN reduce
ELSE IF
   line = 'LOW' THEN increase
ELSE IF
   line = 'END' THEN
BEGIN
WHILE powerlevel[NumPowers] = level DO NumPowers := NumPowers-1;
level := level-1;
END
ELSE IF
   line = 'WAIT' THEN
BEGIN
Z := ReActivate;
Z := X*240.0 + i*Y*240;
ROTATE(ABS(Z))
END
ELSE IF line = 'HILD' THEN motor(induction)
ELSE IF (line = 'REV') THEN        BEGIN
v := YellowPhase;
IF (NOT(v IN [#14..#240])) THEN
WriteLn(' POWER SUPPLY OUT OF SPEC') ELSE specValue := v;
specValidate
END
ELSE IF (line = 'OK') THEN BEGIN
IncomingSupply := True; specValidate END
ELSE IF (line = 'NOK') THEN BEGIN IncomingSupply := False; specValidate END
else    begin
GeneratedPowerLine.IncreasePower(
              'Unknown input power "%s"', [SwitchPower.Current]);    // CHECK: string should not cause problems
end;
END;


end (* AVeryVeryLongFunctionName *) ;  // check that only necessary work is done to align
