/*
  This indenting package has been set up for the style :
    if (xxx)
    {
      statements
    }
*/
     
#define FALSE  0
#define TRUE   1


string C_Keywords;
int    CIndent;

init()
{
  assign_key("C_SmartIndent", '\r');
  C_Keywords = "if|else|for|while|switch|case";
  CIndent = TRUE;
}

CIndentOn()
{
  CIndent = TRUE;
}

CIndentOff()
{
  CIndent = FALSE;
}


C_SmartIndent()
{
  /*
    We use the following rules :
    1) if the current line has a C statement like "if", "while", etc, 
       we will indent to the level of that line.
    2) if the current line ends with a semicolon, then we want to look at
       the previous line. If the previous line also ends in a semicolon, then
       the indentation level should be the same as the current line. If the
       previous line has a C statement on it (and doesn't end in '{'), then
       we will indent to the level of that C statement.
    3) If the current line is blank, then start the line at column 1.
    4) If the current line consists of '}', then indent at the level of the
       current line.
  */
  

  /*
    If we are splitting a line in the middle, just insert a '\r'
  */
  if (!CIndent || !IsCFile() || !is_eol())
  {
    insert("\r");
    return;
  }

  /* Take a look at the last character on this line */
  if (currcol() > 1)
  {
    left();
    lastchar = currchar();
  }
  else
    lastchar = 0;

  gobol();
  CurrlineIndent = 0;

  /*
    If the first char in the line is not whitespace, just append '\r'
  */
  if (currchar() != ' ' && currchar() != '\t')
  {
ins_cr:
    autoindent(CurrlineIndent);
    return;
  }


  cl = currline();
  if ((CurrlineIndent = search_string(cl, "[^ \t]")) < 0)
  {
    /* The line was totally blank. Just perform the usual autoindent. */
    CurrlineIndent = 0;
    goto ins_cr;
  }
  

  /*
    Examine the first char on the line
  */
  firstchar = tonum(substr(cl, CurrlineIndent+1, 1));
  CurrlineIndent = NormalizeColumn(cl, CurrlineIndent+1);
  setcol(CurrlineIndent);
  
  /*
    If the only char on the line is a left brace, indent one more level.
    If the only char was '}' (or anything else), indent at the same level.
  */
  if (firstchar == lastchar)
  {
    autoindent(CurrlineIndent);
    /*
        {_  =>  {          }_  =>  }
                  _                _
                 
    */
    if (lastchar == '{')
      instab();
  }

  else if (search_string(substr(cl, CurrlineIndent, 5), C_Keywords) >= 0)
  {
    autoindent(CurrlineIndent);
  }

  else if (lastchar == ';')
  {
    if (up())
    {
      cl = currline();
      down();  goeol();
      if ((prevIndent = search_string(cl, "[^ \t]")) >= 0)
        if (search_string(substr(cl, prevIndent+1, 5), C_Keywords) >= 0)
          /*
                FOUND KEYWORD                      KEYWORD NOT FOUND
             if (xxx)    =>  if (xxx)            c = d;    =>    c = d;
               a = b;_         a = b;            a = b;_         a = b;
                             _                                   _
          */
          CurrlineIndent = NormalizeColumn(cl, prevIndent + 1);
    }
    autoindent(CurrlineIndent);
  }

  else
    autoindent(CurrlineIndent);
}


autoindent(CurrlineIndent)
{
  goeol();
  insert("\r");
  if (CurrlineIndent)
    setcol(CurrlineIndent);
}

instab()
{
  insert("\t");
  goeol();
}

NormalizeColumn(cl, endcol)
  string cl;
  int    endcol;
{
  col = 1;
  tab_distance = get_option("ta");

  for (i = 1;  i < endcol;  i++)
  {
  	if (substr(cl, i, 1) == "\t")
    {
    	col = (col + tab_distance) / tab_distance * tab_distance + 1;
    }
    else
      col++;
  }
  return col;
}


IsCFile()
{
  currfile = filename();

  if ((i = index(currfile, ".")) > 0)           /* get the extension */
  {
    extension = substr(currfile, i+1, 3);
    if (extension != "c" && extension != "C" && /* is it a C file?   */
        extension != "h" && extension != "H")
      return 0;
    return 1;
  }
  return 0;
}

