package osa.attribute.atgrammar.gui.panels.atgrammar_panels;



import java.util.*;

import javax.swing.*;

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

import osa.attribute.atgrammar.grammar.*;
import osa.attribute.atgrammar.grammar.symbols.*;

/**
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Copyright: </p>
 * <p>Company: </p>
 * @author not attributable
 * @version
 */

public class ATGrammarPanel
  extends JPanel
  {
  public static final Color TERMINALS_COLOR=new Color(255,0,0);
  public static final Color NON_TERMINALS_COLOR=new Color(0,255,0);
  public static final Color OUTPUTS_COLOR=new Color(0,0,255);

  public static final Color SELECTED_COLOR=new Color(128,128,255);
  public static final Color UNSELECTED_COLOR=new Color(255,255,255);


  private class ProductionsListModel
    extends AbstractListModel
    {
    private Grammar grammar_reference;

    private int cursor_row=0;
    private int desirable_cursor_position=0;
    private int actual_cursor_position=0;

    private GrammarProduction current_production;

    public ProductionsListModel(Grammar grammar_reference)
      {
      this.grammar_reference=grammar_reference;
      }

    public void setCursorRowAt(int row)
      {
      current_production=grammar_reference.getProductionAt(row);
      int string_len=current_production.getRightPart().getLength();
      if(this.desirable_cursor_position>string_len)
        {
        actual_cursor_position=string_len;
        }
      else
        {
        actual_cursor_position=desirable_cursor_position;
        }
      cursor_row=row;
      }

    public void incrementCursorPosition()
      {
      if(actual_cursor_position<current_production.getRightPart().getLength())
        {
        actual_cursor_position++;
        }
      System.err.println("position "+actual_cursor_position);
      }

    public void decrementCursorPosition()
      {
      if(actual_cursor_position>0)
        {
        actual_cursor_position--;
        }
      desirable_cursor_position=actual_cursor_position;
      }

    public int getCursorPosition()
      {
      return this.actual_cursor_position;
      }

    public Object getElementAt(int index)
      {
      if(grammar_reference!=null)
        {
        return grammar_reference.getProductionAt(index);
        }
      return null;
      }

    public int getSize()
      {
      if(grammar_reference!=null)
        {
        return grammar_reference.getProductionsCount();
        }
      return -1;
      }
    }

  private class ProductionsListCellRenderer
    implements ListCellRenderer
    {
    public Component getListCellRendererComponent
      (
      JList list,
      Object value,
      int index,
      boolean isSelected,
      boolean cellHasFocus
      )
      {
      if(value instanceof GrammarProduction)
        {
        GrammarProduction current_production;
        current_production=(GrammarProduction)value;

        JPanel cell_pane=new JPanel();
        cell_pane.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));

        Symbol temp_symbol;
        JLabel temp_label;

        temp_symbol=current_production.getLeftPart();

        // left part of production
        temp_label=new JLabel();
        temp_label.setText(temp_symbol.toString()+" ");
        temp_label.setForeground(ATGrammarPanel.NON_TERMINALS_COLOR);
        cell_pane.add(temp_label);

        // --> sign
        temp_label=new JLabel();
        temp_label.setText("-->"+" ");
        temp_label.setForeground(Color.black);
        cell_pane.add(temp_label);


        int cursor_position=0;

        if(isSelected)
          {
          cell_pane.setBackground(SELECTED_COLOR);
          ProductionsListModel model =(ProductionsListModel)list.getModel();
          model.setCursorRowAt(index);
          cursor_position=model.getCursorPosition();
          }
        else
          {
          cell_pane.setBackground(UNSELECTED_COLOR);
          }

        // right part of production
        SymbolsString right_part=current_production.getRightPart();
        int right_part_len=right_part.getLength();
        for(int i=0;i<right_part_len;i++)
           {
           if(isSelected && i==cursor_position)
             {
             temp_label=new JLabel(" # ");
             temp_label.setForeground(Color.magenta);
             cell_pane.add(temp_label);
             }


           temp_label=new JLabel();
           temp_symbol=right_part.getSymbolAt(i);

           temp_label.setText(temp_symbol.toString()+" ");
           switch(temp_symbol.getType())
                 {
                 case Symbol.NON_TERMINAL_SYMBOL:
                   temp_label.setForeground(NON_TERMINALS_COLOR);
                   break;
                 case Symbol.TERMINAL_SYMBOL:
                   temp_label.setForeground(TERMINALS_COLOR);
                   break;
                 case Symbol.OUTPUT_SYMBOL:
                   temp_label.setForeground(OUTPUTS_COLOR);
                   break;
                 default:
                 }
           cell_pane.add(temp_label);
           }

        return cell_pane;
        }
      return null;
      }
    }

  private class ProductionsListKeyListener
    implements KeyListener
    {

    JList subscriber;

    public ProductionsListKeyListener(JList subscriber)
      {
      this.subscriber=subscriber;
      }

    public void keyTyped(KeyEvent e)
      {
//      System.err.println("typed "+e.getKeyCode());
      }

    public void keyPressed(KeyEvent e)
      {
      ProductionsListModel model=(ProductionsListModel)subscriber.getModel();
      int key_code=e.getKeyCode();
      switch(key_code)
            {
            case KeyEvent.VK_UP:
              System.err.println("pressed up");
              break;
            case KeyEvent.VK_DOWN:
              System.err.println("pressed down");
              break;
            case KeyEvent.VK_LEFT:
              System.err.println("pressed left");
              model.decrementCursorPosition();
              subscriber.repaint();
              break;
            case KeyEvent.VK_RIGHT:
              System.err.println("pressed right");
              model.incrementCursorPosition();
              subscriber.repaint();
              break;
            }
      }

    public void keyReleased(KeyEvent e)
      {
//      System.err.println("released "+e.getKeyCode());
      }

    }


  private JList list_of_productions;
  private ProductionsListModel list_of_productions_model;
  private ProductionsListCellRenderer list_of_productions_cell_renderer;


  private Grammar grammar_reference;



  public ATGrammarPanel(Grammar grammar_reference)
    {

    super();

    this.grammar_reference=grammar_reference;

    // preparing list model
    list_of_productions_model=new ProductionsListModel(grammar_reference);
    // preparing list cell renderer
    list_of_productions_cell_renderer=new ProductionsListCellRenderer();

    // preparing list_of_productions;
    list_of_productions=new JList(list_of_productions_model);

    // setting list renderer
    list_of_productions.setCellRenderer(new ProductionsListCellRenderer());

    // list_of_productions.setCellRenderer(list_of_productions_cell_renderer);
    list_of_productions.addKeyListener(new ProductionsListKeyListener(list_of_productions));

    // setting list key_listener



    this.setLayout(new BorderLayout());

    this.add(list_of_productions, BorderLayout.CENTER);
    }

  private int row;
  private int column;
  }