package osa;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.lang.Thread;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.undo.*;

public class Tab4B implements Runnable
{ private MainFrame tFrame;
  private Tab4 tTab4;
  private Tab4B tThis;
  private Thread tThread;

  private Action aFileSaveChain;
  private Action aFileChangeWindowMode;
  private Action aFileClose;
  private Action aGeneratorClear;
  private Action aGeneratorStop;
  private Action aGeneratorUndo;
  private Action aGeneratorRedo;
  private Action aGeneratorNext;
  private Action aHelpHelpTopics;
  private Action aHelpAbout;

  private JPanel t4BPanel = new JPanel();
  private JPanel t4BtPanel = new JPanel();
  private JLabel t4BtTLabel = new JLabel();
  private JList t4BList = new JList();
  private JScrollPane t4BtScrollPane = new JScrollPane();
  private JLabel t4BtBLabel = new JLabel();
  private JPanel t4BbPanel = new JPanel();
  private JPanel t4BbtPanel = new JPanel();
  private JLabel t4BbtLabel = new JLabel();
  public  JSlider t4BSlider = new JSlider(0,10,0);
  private JButton t4BButton = new JButton();
  private JPanel t4BbbPanel = new JPanel();
  private JLabel t4BbbTLabel = new JLabel();
  private JTextArea t4BTextArea = new JTextArea();
  private JScrollPane t4BbScrollPane = new JScrollPane();
  private JPanel t4BbbbPanel = new JPanel();
  private JLabel t4BbbBLabel = new JLabel();
  private JPanel t4BcnPanel = new JPanel();
  private JLabel t4BcnLabel = new JLabel();
  private JTextField t4BcnTextField = new JTextField();

  private String   reSaveChainTextAreaName;
  private volatile int ModeState;

  Tab4B(MainFrame pMainFrame,Tab4 pTab4)
  { tFrame=pMainFrame; tTab4=pTab4; tThis=this; tThread=new Thread(tThis);

    aFileSaveChain = new AbstractAction("Save Chain",new ImageIcon(Tab4B.class.getResource("save.gif")))
    {{ putValue(Action.SHORT_DESCRIPTION,"Save Chain"); }
    // putValue(Action.MNEMONIC_KEY,new Integer(KeyEvent.VK_S));
    public void actionPerformed(ActionEvent e)
    { if((!tThread.isAlive())&&(ModeState==0)) t4BSaveChain(); }};
    aFileChangeWindowMode = new AbstractAction("Change Window Mode",new ImageIcon(Tab4B.class.getResource("window.gif")))
    {{ putValue(Action.SHORT_DESCRIPTION,"Change Window Mode"); }
    // putValue(Action.MNEMONIC_KEY,new Integer(KeyEvent.VK_W));
    public void actionPerformed(ActionEvent e)
    { if(tFrame.ShowTop) { tFrame.ShowTop=false; tFrame.TopHide(); }
      else { tFrame.ShowTop=true; tFrame.TopShow(); } }};
    aFileClose = new AbstractAction("Close",new ImageIcon(Tab4B.class.getResource("close.gif")))
    {{ putValue(Action.SHORT_DESCRIPTION,"Close"); }
    // putValue(Action.MNEMONIC_KEY,new Integer(KeyEvent.VK_L));
    public void actionPerformed(ActionEvent e)
    { if((!tThread.isAlive())&&(ModeState==0)) tFrame.CloseBottom(); }};
    aGeneratorClear = new AbstractAction("Clear",new ImageIcon(Tab4B.class.getResource("delete.gif")))
    {{ putValue(Action.SHORT_DESCRIPTION,"Clear"); }
    // putValue(Action.MNEMONIC_KEY,new Integer(KeyEvent.VK_C));
    public void actionPerformed(ActionEvent e)
    { if((!tThread.isAlive())&&(ModeState==0))
      { tFrame.mWasp.BeginChainGeneration(); t4BUpdate(); }}};
    aGeneratorStop = new AbstractAction("Stop",new ImageIcon(Tab4B.class.getResource("cgstop.gif")))
    {{ putValue(Action.SHORT_DESCRIPTION,"Stop"); }
    // putValue(Action.MNEMONIC_KEY,new Integer(KeyEvent.VK_S));
    public void actionPerformed(ActionEvent e)
    { ModeState=0; }};
    aGeneratorUndo = new AbstractAction("Undo",new ImageIcon(Tab4B.class.getResource("cgundo.gif")))
    {{ putValue(Action.SHORT_DESCRIPTION,"Undo"); }
    // putValue(Action.MNEMONIC_KEY,new Integer(KeyEvent.VK_U));
    public void actionPerformed(ActionEvent e)
    { if((!tThread.isAlive())&&(ModeState==0)) { if(tFrame.SliderValue==0) {
        tFrame.mWasp.Undo(); t4BUpdate(); }
      else {ModeState=1; tThread.start(); tThread=new Thread(tThis); } }}};
    aGeneratorRedo = new AbstractAction("Redo",new ImageIcon(Tab4B.class.getResource("cgredo.gif")))
    {{ putValue(Action.SHORT_DESCRIPTION,"Redo"); }
    // putValue(Action.MNEMONIC_KEY,new Integer(KeyEvent.VK_R));
    public void actionPerformed(ActionEvent e)
    { if((!tThread.isAlive())&&(ModeState==0)) { if(tFrame.SliderValue==0) {
        tFrame.mWasp.Redo(); t4BUpdate(); }
      else {ModeState=2; tThread.start(); tThread=new Thread(tThis); } }}};
    aGeneratorNext = new AbstractAction("Next",new ImageIcon(Tab4B.class.getResource("cgnext.gif")))
    {{ putValue(Action.SHORT_DESCRIPTION,"Next"); }
    // putValue(Action.MNEMONIC_KEY,new Integer(KeyEvent.VK_N));
    public void actionPerformed(ActionEvent e)
    { if((!tThread.isAlive())&&(ModeState==0)) { if(tFrame.SliderValue==0) { int i,q;
        q=tFrame.alCurrentRules.size(); i=tFrame.SelectedRuleNumber;
        if((i>=0)&&(i<q)) tFrame.mWasp.Next(i); t4BUpdate(); }
      else { ModeState=3; tThread.start(); tThread=new Thread(tThis); } }}};
    aHelpHelpTopics = new AbstractAction("Help Topics",new ImageIcon(Tab4B.class.getResource("help.gif")))
    {{ putValue(Action.SHORT_DESCRIPTION,"Help Topics"); }
    // putValue(Action.MNEMONIC_KEY,new Integer(KeyEvent.VK_H));
    public void actionPerformed(ActionEvent e)
    { tFrame.HelpHelpTopics(0x4B); }};
    aHelpAbout = new AbstractAction("About...")
    {{ putValue(Action.SHORT_DESCRIPTION,"About..."); }
    // putValue(Action.MNEMONIC_KEY,new Integer(KeyEvent.VK_A));
    public void actionPerformed(ActionEvent e)
    { if((!tThread.isAlive())&&(ModeState==0)) tFrame.HelpAbout(); }};

    t4BPanel.setLayout(new GridLayout(2,1));
    t4BPanel.add(t4BtPanel);
    t4BPanel.add(t4BbPanel);
    t4BtPanel.setLayout(new BorderLayout());
    t4BtTLabel.setFont(tFrame.mFont);
    t4BtTLabel.setText("  ");//Альт.правила, шаг 100:
    t4BtPanel.add(t4BtTLabel,BorderLayout.NORTH);
    t4BList.setFont(tFrame.mFont);
    t4BList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    t4BList.addListSelectionListener(new ListSelectionListener()
    { public void valueChanged(ListSelectionEvent e)
      { tFrame.SelectedRuleNumber=t4BList.getSelectedIndex(); }});
    t4BtScrollPane.setViewportView(t4BList);
    t4BtPanel.add(t4BtScrollPane,BorderLayout.CENTER);
    t4BtBLabel.setFont(tFrame.mFont);
    t4BtBLabel.setText("  ");//Кол-во правил
    t4BtPanel.add(t4BtBLabel,BorderLayout.SOUTH);
//Нижняя панель
    t4BbPanel.setLayout(new BorderLayout());
    t4BbPanel.add(t4BbtPanel,BorderLayout.NORTH);
    t4BbPanel.add(t4BbbPanel,BorderLayout.CENTER);
//Нижняя верхняя панель
    t4BbtPanel.setLayout(new BorderLayout());
    t4BbtLabel.setFont(tFrame.mFont);
    t4BbtLabel.setText("  Скорость Вывода: ");
    t4BbtPanel.add(t4BbtLabel,BorderLayout.WEST);
    t4BSlider.setFont(tFrame.mFont);
    t4BSlider.setMajorTickSpacing(1);
    t4BSlider.setPaintTicks(true);
    t4BSlider.setSnapToTicks(true);
    t4BSlider.setPaintLabels(true);
    t4BSlider.setValue(tFrame.SliderValue);
    t4BSlider.setFocusable(false);
    t4BSlider.addChangeListener(new ChangeListener()
    { public void stateChanged(ChangeEvent e)
      { tFrame.SliderValue=t4BSlider.getValue(); }});
    t4BbtPanel.add(t4BSlider,BorderLayout.CENTER);
    t4BButton.setFont(tFrame.mFont);
    t4BButton.setText("  ");
    t4BButton.setFocusable(false);
    t4BButton.addActionListener(new ActionListener()
    { public void actionPerformed(ActionEvent e)
      { if((!tThread.isAlive())&&(ModeState==0)&&(tFrame.CurrentStepNumber<=0))
        { tFrame.RightStyle=!tFrame.RightStyle;//tFrame.mWasp.CurrentChainUpdate();
          tFrame.mWasp.BeginChainGeneration(); t4BUpdate(); } }});
    t4BbtPanel.add(t4BButton,BorderLayout.EAST);
//Нижняя нижняя панель
    t4BbbPanel.setLayout(new BorderLayout());
    t4BbbTLabel.setFont(tFrame.mFont);
    t4BbbTLabel.setText("  Текст Цепочки:");
    t4BbbPanel.add(t4BbbTLabel,BorderLayout.NORTH);
    t4BTextArea.setFont(tFrame.mFont);
    t4BTextArea.setTabSize(0x08);
    t4BTextArea.setEditable(false);
    t4BTextArea.getCaret().setVisible(false);
    t4BTextArea.getCaret().setSelectionVisible(true);
    t4BbScrollPane.setViewportView(t4BTextArea);
    t4BbbPanel.add(t4BbScrollPane,BorderLayout.CENTER);
    t4BbbPanel.add(t4BbbbPanel,BorderLayout.SOUTH);
//Нижняя нижняя нижняя панель
    t4BbbbPanel.setLayout(new BorderLayout());
    t4BbbBLabel.setFont(tFrame.mFont);
    t4BbbBLabel.setText("  ");//Длина Цепочки
    t4BbbbPanel.add(t4BbbBLabel,BorderLayout.WEST);
    t4BbbBLabel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
    t4BbbbPanel.add(t4BcnPanel,BorderLayout.CENTER);
    t4BcnPanel.setLayout(new BorderLayout());
    t4BcnLabel.setFont(tFrame.mFont);
    t4BcnLabel.setText("  Chain Name: ");
    t4BcnPanel.add(t4BcnLabel,BorderLayout.WEST);
    t4BcnTextField.setFont(tFrame.mFont);
    t4BcnTextField.setEditable(true);
    t4BcnTextField.getCaret().setVisible(true);
    t4BcnTextField.getCaret().setSelectionVisible(true);
    t4BcnPanel.add(t4BcnTextField,BorderLayout.CENTER);

    reSaveChainTextAreaName="";
    ModeState=0;
  }

  public void run()
  { int i,q;
    switch(ModeState)
    { case 1: do
        { tFrame.mWasp.Undo(); t4BUpdate();
          if(!tFrame.mWasp.CanUndo()) ModeState=0;
          i=tFrame.SliderValue; if((ModeState!=0)&&(i>=1)&&(i<=10))
          { try{ tThread.sleep((10-i)*(10-i)*50+1); }catch(Exception ex){}; }
          else ModeState=0;
        } while(ModeState!=0); t4BUpdate(); break;
      case 2: do
        { tFrame.mWasp.Redo(); t4BUpdate();
          if(!tFrame.mWasp.CanRedo()) ModeState=0;
          i=tFrame.SliderValue; if((ModeState!=0)&&(i>=1)&&(i<=10))
          { try{ tThread.sleep((10-i)*(10-i)*50+1); }catch(Exception ex){}; }
          else ModeState=0;
        } while(ModeState!=0); t4BUpdate(); break;
      case 3: do
        { q=tFrame.alCurrentRules.size(); i=tFrame.SelectedRuleNumber;
          if((i>=0)&&(i<q)) tFrame.mWasp.Next(i); t4BUpdate();
          if(!tFrame.mWasp.CanNext()) ModeState=0;
          i=tFrame.SliderValue; if((ModeState!=0)&&(i>=1)&&(i<=10))
          { try{ tThread.sleep((10-i)*(10-i)*50+1); }catch(Exception ex){}; }
          else ModeState=0;
        } while(ModeState!=0); t4BUpdate(); break;
    }
  }

  public void t4BUpdate()
  { int i,q; String s,sn; Object o[];
    t4BTextArea.selectAll();
    t4BTextArea.replaceSelection(tFrame.ArrayListToString(tFrame.alCurrentChain));
    t4BTextArea.setCaretPosition(0);
    if((tFrame.sLine>=0)&&(tFrame.sLine<t4BTextArea.getLineCount())) try
    { i=t4BTextArea.getLineStartOffset(tFrame.sLine);
      q=t4BTextArea.getLineEndOffset(tFrame.sLine);
      if(q != (t4BTextArea.getLineCount()-1)) --q;
      if((tFrame.RightStyle)&&(i<q)) t4BTextArea.setCaretPosition(q-1);
      if((tFrame.sStart>=0)&&(tFrame.sLength>=0)
        &&(tFrame.sStart+tFrame.sLength<=q-i))
      { t4BTextArea.setSelectionStart(i+tFrame.sStart);
        t4BTextArea.setSelectionEnd(i+tFrame.sStart+tFrame.sLength); }
      } catch(Exception e) {};
    s = new String(Integer.toString(tFrame.ccLength)); i=s.length();
    switch(i)
    { case 1: sn=new String("    "+s); break;
      case 2: sn=new String("   " +s); break;
      case 3: sn=new String("  "  +s); break;
      case 4: sn=new String(" "   +s); break;
      default:sn=new String("     "); break; }
    t4BbbBLabel.setText("  Длина Цепочки: "+sn+"  ");
    t4BSlider.setValue(tFrame.SliderValue);
    if(tFrame.RightStyle) t4BButton.setText("Правый Вывод");
    else t4BButton.setText("Левый  Вывод");
    if(tFrame.mWasp.CanNext())
    { q=tFrame.alCurrentRules.size(); o = new Object[q];
      for(i=0;i<q;++i) o[i]=tFrame.alCurrentRules.get(i);
      i=tFrame.SelectedRuleNumber; t4BList.setListData(o); if((i>=0)&&(i<q))
      { t4BList.setSelectedIndex(i); t4BList.ensureIndexIsVisible(i);
        tFrame.SelectedRuleNumber=i; } else tFrame.SelectedRuleNumber=-1;
      t4BtTLabel.setText("  Альтернативные Правила После "
        +tFrame.CurrentStepNumber+" Подстановок:");
      t4BtBLabel.setText("  Количество Правил: "+q); }
    else { o = new Object[1];
      o[0]="  Вывод Цепочки Окончен  "; t4BList.setListData(o);
      t4BList.setSelectedIndex(0); t4BList.ensureIndexIsVisible(0);
      t4BtTLabel.setText("  Альтернативные Правила После "
        +tFrame.CurrentStepNumber+" Подстановок:");
      t4BtBLabel.setText("  Количество Правил: 0"); }
    if(ModeState!=0)
    { aFileSaveChain.setEnabled(false); aFileClose.setEnabled(false);
      aHelpAbout.setEnabled(false); aGeneratorClear.setEnabled(false);
      aGeneratorUndo.setEnabled(false); aGeneratorRedo.setEnabled(false);
      aGeneratorNext.setEnabled(false); aGeneratorStop.setEnabled(true);
      t4BButton.setEnabled(false); }
    else { aFileSaveChain.setEnabled(true); aFileClose.setEnabled(true);
      aHelpAbout.setEnabled(true); aGeneratorClear.setEnabled(true);
      aGeneratorStop.setEnabled(false);
      if(tFrame.mWasp.CanUndo()) aGeneratorUndo.setEnabled(true);
      else aGeneratorUndo.setEnabled(false);
      if(tFrame.mWasp.CanRedo()) aGeneratorRedo.setEnabled(true);
      else aGeneratorRedo.setEnabled(false);
      if(tFrame.mWasp.CanNext()) aGeneratorNext.setEnabled(true);
      else aGeneratorNext.setEnabled(false);
      if(tFrame.CurrentStepNumber<=0) t4BButton.setEnabled(true);
      else t4BButton.setEnabled(false); }
  }

  public void t4BSaveChain()
  { String s; ArrayList al = new ArrayList(t4BTextArea.getLineCount());
    tFrame.TextAreaToArrayList(t4BTextArea,al,true);
    s=tFrame.StringToBegin(tFrame.StringNormalize(t4BcnTextField.getText(),false));
    if(tTab4.SaveChain(reSaveChainTextAreaName,s,al))
    { tFrame.reSaveChains=true; reSaveChainTextAreaName=s; }
  }

  public boolean tClose()
  { boolean r=false;
    if((!tThread.isAlive())&&(ModeState==0)) {
      tFrame.mMenuBar.removeAll();
      tFrame.mToolBar.removeAll();
      tFrame.mSplitPane.setBottomComponent(null);
      tFrame.alCurrentChain.clear();
      tFrame.alCurrentRules.clear();
      reSaveChainTextAreaName="";
      t4BTextArea.selectAll(); t4BTextArea.replaceSelection("");
      t4BcnTextField.selectAll(); t4BcnTextField.replaceSelection("");
      t4BList.setListData(new Object[0]);
      tFrame.validate(); r=true; }
    return(r);
  }

  public void tOpen()
  {
    tFrame.mSplitPane.setBottomComponent(t4BPanel);

    tFrame.isNew=true;
    reSaveChainTextAreaName = "\t";
    t4BcnTextField.selectAll();
    t4BcnTextField.replaceSelection("New Chain");
    t4BcnTextField.setCaretPosition(0);
    t4BTextArea.selectAll();
    t4BTextArea.replaceSelection("");
    tFrame.mWasp.BeginChainGeneration();
    t4BUpdate();
    JMenu jMenu;
    jMenu = new JMenu("File");
    jMenu.setMnemonic(KeyEvent.VK_F);
    tFrame.mMenuBar.add(jMenu);
    jMenu.add(aFileSaveChain).setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,Event.CTRL_MASK));
    jMenu.addSeparator();
    jMenu.add(aFileChangeWindowMode).setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W,Event.ALT_MASK));
    jMenu.addSeparator();
    jMenu.add(aFileClose).setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,Event.ALT_MASK));
    jMenu = new JMenu("Generator");
    jMenu.setMnemonic(KeyEvent.VK_G);
    tFrame.mMenuBar.add(jMenu);
    jMenu.add(aGeneratorClear).setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE,Event.CTRL_MASK));
    jMenu.add(aGeneratorStop).setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE,0));
//    jMenu.add(aGeneratorUndo).setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F3,Event.CTRL_MASK));
//    jMenu.add(aGeneratorRedo).setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4,Event.CTRL_MASK));
    jMenu.add(aGeneratorNext).setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,0));
    jMenu = new JMenu("Help");
    jMenu.setMnemonic(KeyEvent.VK_H);
    tFrame.mMenuBar.add(jMenu);
    jMenu.add(aHelpHelpTopics).setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1,0));
    jMenu.addSeparator();
    jMenu.add(aHelpAbout);//.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A,Event.ALT_MASK));
    JButton jButton; Insets jInsets=new Insets(2,2,2,2);
    jButton=tFrame.mToolBar.add(aFileSaveChain);
    jButton.setFocusable(false); jButton.setMargin(jInsets);
    tFrame.mToolBar.addSeparator();
    jButton=tFrame.mToolBar.add(aFileChangeWindowMode);
    jButton.setFocusable(false); jButton.setMargin(jInsets);
    tFrame.mToolBar.addSeparator();
    jButton=tFrame.mToolBar.add(aFileClose);
    jButton.setFocusable(false); jButton.setMargin(jInsets);
    tFrame.mToolBar.addSeparator();
    jButton=tFrame.mToolBar.add(aGeneratorClear);
    jButton.setFocusable(false); jButton.setMargin(jInsets);
    tFrame.mToolBar.addSeparator();
    jButton=tFrame.mToolBar.add(aGeneratorStop);
    jButton.setFocusable(false); jButton.setMargin(jInsets);
//    tFrame.mToolBar.add(aGeneratorUndo).setFocusable(false);
//    tFrame.mToolBar.add(aGeneratorRedo).setFocusable(false);
    jButton=tFrame.mToolBar.add(aGeneratorNext);
    jButton.setFocusable(false); jButton.setMargin(jInsets);
    tFrame.validate();
  }
}
