/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */

/*
  Part of the Processing project - http://processing.org

  Copyright (c) 2004-08 Ben Fry and Casey Reas
  Copyright (c) 2001-04 Massachusetts Institute of Technology

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software Foundation,
  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

package processing.app;

import processing.app.syntax.*;

import java.awt.*;
import java.awt.event.*;


/**
 * Filters key events for tab expansion/indent/etc.
 * <p/>
 * For version 0099, some changes have been made to make the indents
 * smarter. There are still issues though:
 * + indent happens when it picks up a curly brace on the previous line,
 *   but not if there's a  blank line between them.
 * + It also doesn't handle single indent situations where a brace
 *   isn't used (i.e. an if statement or for loop that's a single line).
 *   It shouldn't actually be using braces.
 * Solving these issues, however, would probably best be done by a
 * smarter parser/formatter, rather than continuing to hack this class.
 */
public class EditorListener {
  private Editor editor;
  private JEditTextArea textarea;

  private boolean externalEditor;
  private boolean tabsExpand;
  private boolean tabsIndent;
  private int tabSize;
  private String tabString;
  private boolean autoIndent;

//  private int selectionStart, selectionEnd;
//  private int position;

  /** ctrl-alt on windows and linux, cmd-alt on mac os x */
  static final int CTRL_ALT = ActionEvent.ALT_MASK |
    Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();


  public EditorListener(Editor editor, JEditTextArea textarea) {
    this.editor = editor;
    this.textarea = textarea;

    // let him know that i'm leechin'
    textarea.editorListener = this;

    applyPreferences();
  }


  public void applyPreferences() {
    tabsExpand = Preferences.getBoolean("editor.tabs.expand");
    //tabsIndent = Preferences.getBoolean("editor.tabs.indent");
    tabSize = Preferences.getInteger("editor.tabs.size");
    tabString = Editor.EMPTY.substring(0, tabSize);
    autoIndent = Preferences.getBoolean("editor.indent");
    externalEditor = Preferences.getBoolean("editor.external");
  }


  //public void setExternalEditor(boolean externalEditor) {
  //this.externalEditor = externalEditor;
  //}


  /**
   * Intercepts key pressed events for JEditTextArea.
   * <p/>
   * Called by JEditTextArea inside processKeyEvent(). Note that this
   * won't intercept actual characters, because those are fired on
   * keyTyped().
   * @return true if the event has been handled (to remove it from the queue)
   */
  public boolean keyPressed(KeyEvent event) {
    // don't do things if the textarea isn't editable
    if (externalEditor) return false;

    //deselect();  // this is for paren balancing
    char c = event.getKeyChar();
    int code = event.getKeyCode();

//    if (code == KeyEvent.VK_SHIFT) {
//      editor.toolbar.setShiftPressed(true);
//    }

    //System.out.println((int)c + " " + code + " " + event);
    //System.out.println();

    Sketch sketch = editor.getSketch();

    if ((event.getModifiers() & CTRL_ALT) == CTRL_ALT) {
      if (code == KeyEvent.VK_LEFT) {
        sketch.handlePrevCode();
        return true;
      } else if (code == KeyEvent.VK_RIGHT) {
        sketch.handleNextCode();
        return true;
      }
    }

    if ((event.getModifiers() & KeyEvent.CTRL_MASK) != 0) {
      // Consume ctrl-m(carriage return) keypresses
      if (code == KeyEvent.VK_M) {
        event.consume();  // does nothing
        return false;
      }
    }

    if ((event.getModifiers() & KeyEvent.META_MASK) != 0) {
      //event.consume();  // does nothing
      return false;
    }

    // TODO i don't like these accessors. clean em up later.
    if (!editor.getSketch().isModified()) {
      if ((code == KeyEvent.VK_BACK_SPACE) || (code == KeyEvent.VK_TAB) ||
          (code == KeyEvent.VK_ENTER) || ((c >= 32) && (c < 128))) {
        sketch.setModified(true);
      }
    }

    if ((code == KeyEvent.VK_UP) &&
        ((event.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
      // back up to the last empty line
      char contents[] = textarea.getText().toCharArray();
      //int origIndex = textarea.getCaretPosition() - 1;
      int caretIndex = textarea.getCaretPosition();

      int index = calcLineStart(caretIndex - 1, contents);
      //System.out.println("line start " + (int) contents[index]);
      index -= 2;  // step over the newline
      //System.out.println((int) contents[index]);
      boolean onlySpaces = true;
      while (index > 0) {
        if (contents[index] == 10) {
          if (onlySpaces) {
            index++;
            break;
          } else {
            onlySpaces = true;  // reset
          }
        } else if (contents[index] != ' ') {
          onlySpaces = false;
        }
        index--;
      }
      // if the first char, index will be -2
      if (index < 0) index = 0;

      if ((event.getModifiers() & KeyEvent.SHIFT_MASK) != 0) {
        textarea.setSelectionStart(caretIndex);
        textarea.setSelectionEnd(index);
      } else {
        textarea.setCaretPosition(index);
      }
      event.consume();
      return true;

    } else if ((code == KeyEvent.VK_DOWN) &&
               ((event.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
      char contents[] = textarea.getText().toCharArray();
      int caretIndex = textarea.getCaretPosition();

      int index = caretIndex;
      int lineStart = 0;
      boolean onlySpaces = false;  // don't count this line
      while (index < contents.length) {
        if (contents[index] == 10) {
          if (onlySpaces) {
            index = lineStart;  // this is it
            break;
          } else {
            lineStart = index + 1;
            onlySpaces = true;  // reset
          }
        } else if (contents[index] != ' ') {
          onlySpaces = false;
        }
        index++;
      }
      // if the first char, index will be -2
      //if (index < 0) index = 0;

      //textarea.setSelectionStart(index);
      //textarea.setSelectionEnd(index);
      if ((event.getModifiers() & KeyEvent.SHIFT_MASK) != 0) {
        textarea.setSelectionStart(caretIndex);
        textarea.setSelectionEnd(index);
      } else {
        textarea.setCaretPosition(index);
      }
      event.consume();
      return true;
    }


    switch ((int) c) {

    case 9:  // TAB
      if (textarea.isSelectionActive()) {
        boolean outdent = (event.getModifiers() & KeyEvent.SHIFT_MASK) != 0;
        editor.handleIndentOutdent(!outdent);

      } else if (tabsExpand) {  // expand tabs
        textarea.setSelectedText(tabString);
        event.consume();
        return true;

      } else if (tabsIndent) {
        // this code is incomplete

        // if this brace is the only thing on the line, outdent
        //char contents[] = getCleanedContents();
        char contents[] = textarea.getText().toCharArray();
        // index to the character to the left of the caret
        int prevCharIndex = textarea.getCaretPosition() - 1;

        // now find the start of this line
        int lineStart = calcLineStart(prevCharIndex, contents);

        int lineEnd = lineStart;
        while ((lineEnd < contents.length - 1) &&
               (contents[lineEnd] != 10)) {
          lineEnd++;
        }

        // get the number of braces, to determine whether this is an indent
        int braceBalance = 0;
        int index = lineStart;
        while ((index < contents.length) &&
               (contents[index] != 10)) {
          if (contents[index] == '{') {
            braceBalance++;
          } else if (contents[index] == '}') {
            braceBalance--;
          }
          index++;
        }

        // if it's a starting indent, need to ignore it, so lineStart
        // will be the counting point. but if there's a closing indent,
        // then the lineEnd should be used.
        int where = (braceBalance > 0) ? lineStart : lineEnd;
        int indent = calcBraceIndent(where, contents);
        if (indent == -1) {
          // no braces to speak of, do nothing
          indent = 0;
        } else {
          indent += tabSize;
        }

        // and the number of spaces it has
        int spaceCount = calcSpaceCount(prevCharIndex, contents);

        textarea.setSelectionStart(lineStart);
        textarea.setSelectionEnd(lineStart + spaceCount);
        textarea.setSelectedText(Editor.EMPTY.substring(0, indent));

        event.consume();
        return true;
      }
      break;

    case 10:  // auto-indent
    case 13:
      if (autoIndent) {
        char contents[] = textarea.getText().toCharArray();

        // this is the previous character
        // (i.e. when you hit return, it'll be the last character
        // just before where the newline will be inserted)
        int origIndex = textarea.getCaretPosition() - 1;

        // NOTE all this cursing about CRLF stuff is probably moot
        // NOTE since the switch to JEditTextArea, which seems to use
        // NOTE only LFs internally (thank god). disabling for 0099.
        // walk through the array to the current caret position,
        // and count how many weirdo windows line endings there are,
        // which would be throwing off the caret position number
        /*
        int offset = 0;
        int realIndex = origIndex;
        for (int i = 0; i < realIndex-1; i++) {
          if ((contents[i] == 13) && (contents[i+1] == 10)) {
            offset++;
            realIndex++;
          }
        }
        // back up until \r \r\n or \n.. @#($* cross platform
        //System.out.println(origIndex + " offset = " + offset);
        origIndex += offset; // ARGH!#(* WINDOWS#@($*
        */

        // if the previous thing is a brace (whether prev line or
        // up farther) then the correct indent is the number of spaces
        // on that line + 'indent'.
        // if the previous line is not a brace, then just use the
        // identical indentation to the previous line

        // calculate the amount of indent on the previous line
        // this will be used *only if the prev line is not an indent*
        int spaceCount = calcSpaceCount(origIndex, contents);

        // If the last character was a left curly brace, then indent.
        // For 0122, walk backwards a bit to make sure that the there
        // isn't a curly brace several spaces (or lines) back. Also
        // moved this before calculating extraCount, since it'll affect
        // that as well.
        int index2 = origIndex;
        while ((index2 >= 0) &&
               Character.isWhitespace(contents[index2])) {
          index2--;
        }
        if (index2 != -1) {
          // still won't catch a case where prev stuff is a comment
          if (contents[index2] == '{') {
            // intermediate lines be damned,
            // use the indent for this line instead
            spaceCount = calcSpaceCount(index2, contents);
            spaceCount += tabSize;
          }
        }
        //System.out.println("spaceCount should be " + spaceCount);

        // now before inserting this many spaces, walk forward from
        // the caret position and count the number of spaces,
        // so that the number of spaces aren't duplicated again
        int index = origIndex + 1;
        int extraCount = 0;
        while ((index < contents.length) &&
               (contents[index] == ' ')) {
          //spaceCount--;
          extraCount++;
          index++;
        }
        int braceCount = 0;
        while ((index < contents.length) && (contents[index] != '\n')) {
          if (contents[index] == '}') {
            braceCount++;
          }
          index++;
        }

        // hitting return on a line with spaces *after* the caret
        // can cause trouble. for 0099, was ignoring the case, but this is
        // annoying, so in 0122 we're trying to fix that.
        /*
        if (spaceCount - extraCount > 0) {
          spaceCount -= extraCount;
        }
        */
        spaceCount -= extraCount;
        //if (spaceCount < 0) spaceCount = 0;
        //System.out.println("extraCount is " + extraCount);

        // now, check to see if the current line contains a } and if so,
        // outdent again by indent
        //if (braceCount > 0) {
        //spaceCount -= 2;
        //}

        if (spaceCount < 0) {
          // for rev 0122, actually delete extra space
          //textarea.setSelectionStart(origIndex + 1);
          textarea.setSelectionEnd(textarea.getSelectionStop() - spaceCount);
          textarea.setSelectedText("\n");
        } else {
          String insertion = "\n" + Editor.EMPTY.substring(0, spaceCount);
          textarea.setSelectedText(insertion);
        }

        // not gonna bother handling more than one brace
        if (braceCount > 0) {
          int sel = textarea.getSelectionStart();
          // sel - tabSize will be -1 if start/end parens on the same line
          // http://dev.processing.org/bugs/show_bug.cgi?id=484
          if (sel - tabSize >= 0) {
            textarea.select(sel - tabSize, sel);
            String s = Editor.EMPTY.substring(0, tabSize);
            // if these are spaces that we can delete
            if (textarea.getSelectedText().equals(s)) {
              textarea.setSelectedText("");
            } else {
              textarea.select(sel, sel);
            }
          }
        }
      } else {
        // Enter/Return was being consumed by somehow even if false
        // was returned, so this is a band-aid to simply fire the event again.
        // http://dev.processing.org/bugs/show_bug.cgi?id=1073
        textarea.setSelectedText(String.valueOf(c));
      }
      // mark this event as already handled (all but ignored)
      event.consume();
      return true;

    case '}':
      if (autoIndent) {
        // first remove anything that was there (in case this multiple
        // characters are selected, so that it's not in the way of the
        // spaces for the auto-indent
        if (textarea.getSelectionStart() != textarea.getSelectionStop()) {
          textarea.setSelectedText("");
        }

        // if this brace is the only thing on the line, outdent
        char contents[] = textarea.getText().toCharArray();
        // index to the character to the left of the caret
        int prevCharIndex = textarea.getCaretPosition() - 1;

        // backup from the current caret position to the last newline,
        // checking for anything besides whitespace along the way.
        // if there's something besides whitespace, exit without
        // messing any sort of indenting.
        int index = prevCharIndex;
        boolean finished = false;
        while ((index != -1) && (!finished)) {
          if (contents[index] == 10) {
            finished = true;
            index++;
          } else if (contents[index] != ' ') {
            // don't do anything, this line has other stuff on it
            return false;
          } else {
            index--;
          }
        }
        if (!finished) return false;  // brace with no start
        int lineStartIndex = index;

        int pairedSpaceCount = calcBraceIndent(prevCharIndex, contents); //, 1);
        if (pairedSpaceCount == -1) return false;

        textarea.setSelectionStart(lineStartIndex);
        textarea.setSelectedText(Editor.EMPTY.substring(0, pairedSpaceCount));

        // mark this event as already handled
        event.consume();
        return true;
      }
      break;
    }
    return false;
  }


//  public boolean keyReleased(KeyEvent event) {
//    if (code == KeyEvent.VK_SHIFT) {
//      editor.toolbar.setShiftPressed(false);
//    }
//  }


  public boolean keyTyped(KeyEvent event) {
    char c = event.getKeyChar();

    if ((event.getModifiers() & KeyEvent.CTRL_MASK) != 0) {
      // on linux, ctrl-comma (prefs) being passed through to the editor
      if (c == KeyEvent.VK_COMMA) {
        event.consume();
        return true;
      }
    }
    return false;
  }



  /**
   * Return the index for the first character on this line.
   */
  protected int calcLineStart(int index, char contents[]) {
    // backup from the current caret position to the last newline,
    // so that we can figure out how far this line was indented
    /*int spaceCount = 0;*/
    boolean finished = false;
    while ((index != -1) && (!finished)) {
      if ((contents[index] == 10) ||
          (contents[index] == 13)) {
        finished = true;
        //index++; // maybe ?
      } else {
        index--;  // new
      }
    }
    // add one because index is either -1 (the start of the document)
    // or it's the newline character for the previous line
    return index + 1;
  }


  /**
   * Calculate the number of spaces on this line.
   */
  protected int calcSpaceCount(int index, char contents[]) {
    index = calcLineStart(index, contents);

    int spaceCount = 0;
    // now walk forward and figure out how many spaces there are
    while ((index < contents.length) && (index >= 0) &&
           (contents[index++] == ' ')) {
      spaceCount++;
    }
    return spaceCount;
  }


  /**
   * Walk back from 'index' until the brace that seems to be
   * the beginning of the current block, and return the number of
   * spaces found on that line.
   */
  protected int calcBraceIndent(int index, char contents[]) {
    // now that we know things are ok to be indented, walk
    // backwards to the last { to see how far its line is indented.
    // this isn't perfect cuz it'll pick up commented areas,
    // but that's not really a big deal and can be fixed when
    // this is all given a more complete (proper) solution.
    int braceDepth = 1;
    boolean finished = false;
    while ((index != -1) && (!finished)) {
      if (contents[index] == '}') {
        // aww crap, this means we're one deeper
        // and will have to find one more extra {
        braceDepth++;
        //if (braceDepth == 0) {
        //finished = true;
        //}
        index--;
      } else if (contents[index] == '{') {
        braceDepth--;
        if (braceDepth == 0) {
          finished = true;
        }
        index--;
      } else {
        index--;
      }
    }
    // never found a proper brace, be safe and don't do anything
    if (!finished) return -1;

    // check how many spaces on the line with the matching open brace
    //int pairedSpaceCount = calcSpaceCount(index, contents);
    //System.out.println(pairedSpaceCount);
    return calcSpaceCount(index, contents);
  }


  /**
   * Get the character array and blank out the commented areas.
   * This hasn't yet been tested, the plan was to make auto-indent
   * less gullible (it gets fooled by braces that are commented out).
   */
  protected char[] getCleanedContents() {
    char c[] = textarea.getText().toCharArray();

    int index = 0;
    while (index < c.length - 1) {
      if ((c[index] == '/') && (c[index+1] == '*')) {
        c[index++] = 0;
        c[index++] = 0;
        while ((index < c.length - 1) &&
               !((c[index] == '*') && (c[index+1] == '/'))) {
          c[index++] = 0;
        }

      } else if ((c[index] == '/') && (c[index+1] == '/')) {
        // clear out until the end of the line
        while ((index < c.length) && (c[index] != 10)) {
          c[index++] = 0;
        }
        if (index != c.length) {
          index++;  // skip over the newline
        }
      }
    }
    return c;
  }

  /*
  protected char[] getCleanedContents() {
    char c[] = textarea.getText().toCharArray();
    boolean insideMulti;  // multi-line comment
    boolean insideSingle;  // single line double slash

    //for (int i = 0; i < c.length - 1; i++) {
    int index = 0;
    while (index < c.length - 1) {
      if (insideMulti && (c[index] == '*') && (c[index+1] == '/')) {
        insideMulti = false;
        index += 2;
      } else if ((c[index] == '/') && (c[index+1] == '*')) {
        insideMulti = true;
        index += 2;
      } else if ((c[index] == '/') && (c[index+1] == '/')) {
        // clear out until the end of the line
        while (c[index] != 10) {
          c[index++] = 0;
        }
        index++;
      }
    }
  }
  */
}
