package osa;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;

public class Tab5A
{ private MainFrame tFrame;

  private Action aFileChangeWindowMode;
  private Action aFileClose;
  private Action aFileGenerateFunctions;
  private Action aHelpHelpTopics;
  private Action aHelpAbout;
  private JPanel t5APanel = new JPanel();
  private JPanel t5ABPanel = new JPanel();
  private JPanel t5ATPanel = new JPanel();
  private JLabel t5ATLabel = new JLabel();
  private JList t5ATList = new JList();
  private JScrollPane t5ATScrollPane = new JScrollPane();
  private JLabel t5AStatus = new JLabel();
  private JPanel t5ALPanel = new JPanel();
  private JLabel t5ALLabel = new JLabel();
  private JList t5ALList = new JList();
  private JScrollPane t5ALScrollPane = new JScrollPane();
  private JButton t5ALButton = new JButton();
  private JPanel t5ARPanel = new JPanel();
  private JLabel t5ARLabel = new JLabel();
  private JList t5ARList = new JList();
  private JScrollPane t5ARScrollPane = new JScrollPane();
  private JButton t5ARButton = new JButton();

  private Random rnd = new Random();
  private String RuleArray[];
  private ArrayList alTrainingSelection = new ArrayList(0x200);
  private int ec,cec;

  Tab5A(MainFrame pMainFrame)
  { tFrame=pMainFrame;

    aFileGenerateFunctions = new AbstractAction("Generate Functions",new ImageIcon(Tab5A.class.getResource("generate.gif")))
    {{ putValue(Action.SHORT_DESCRIPTION,"Generate Functions"); }
    // putValue(Action.MNEMONIC_KEY,new Integer(KeyEvent.VK_G));
    public void actionPerformed(ActionEvent e)
    { Generator(); }};
    aFileChangeWindowMode = new AbstractAction("Change Window Mode",new ImageIcon(Tab5A.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(Tab5A.class.getResource("close.gif")))
    {{ putValue(Action.SHORT_DESCRIPTION,"Close"); }
    // putValue(Action.MNEMONIC_KEY,new Integer(KeyEvent.VK_L));
    public void actionPerformed(ActionEvent e)
    { tFrame.CloseBottom(); }};
    aHelpHelpTopics = new AbstractAction("Help Topics",new ImageIcon(Tab5A.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(0x5A); }};
    aHelpAbout = new AbstractAction("About...")
    {{ putValue(Action.SHORT_DESCRIPTION,"About..."); }
    // putValue(Action.MNEMONIC_KEY,new Integer(KeyEvent.VK_A));
    public void actionPerformed(ActionEvent e)
    { tFrame.HelpAbout(); }};

    t5APanel.setLayout(new GridLayout(2,1));
    t5APanel.add(t5ATPanel);
    t5APanel.add(t5ABPanel);
    t5ABPanel.setLayout(new GridLayout(1,2));
    t5ABPanel.add(t5ALPanel);
    t5ABPanel.add(t5ARPanel);

    t5ATPanel.setLayout(new BorderLayout());
    t5ATLabel.setFont(tFrame.mFont);
    t5ATLabel.setText("  Правила Грамматики:");
    t5ATPanel.add(t5ATLabel,BorderLayout.NORTH);
    t5ATList.setFont(tFrame.mFont);
    t5ATList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    t5ATList.addListSelectionListener(new ListSelectionListener()
    { public void valueChanged(ListSelectionEvent e) { int i,j,q; ArrayList al,ta;
      t5ARButton.setEnabled(false); t5ARList.setListData(new Object[0]);
      i=t5ATList.getSelectedIndex(); if((i>=0)&&(i<alTrainingSelection.size()))
      { al=(ArrayList)alTrainingSelection.get(i); q=al.size(); ta = new ArrayList(q);
        for(i=0;i<q;++i) { j=((Integer)al.get(i)).intValue();
        if((j>=0)&&(j<tFrame.alTerminalList.size()))
          ta.add((String)tFrame.alTerminalList.get(j)); else ta.add(""); }
      t5ARList.setListData(ta.toArray()); } UpdateButton(); }});
    t5ATScrollPane.setViewportView(t5ATList);
    t5ATPanel.add(t5ATScrollPane,BorderLayout.CENTER);
    t5AStatus.setFont(tFrame.mFont);
    t5AStatus.setText("  ");
    t5ATPanel.add(t5AStatus,BorderLayout.SOUTH);

    t5ALPanel.setLayout(new BorderLayout());
    t5ALLabel.setFont(tFrame.mFont);
    t5ALLabel.setText("  Терминалы Грамматики:");
    t5ALPanel.add(t5ALLabel,BorderLayout.NORTH);
    t5ALList.setFont(tFrame.mFont);
    t5ALList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    t5ALList.addListSelectionListener(new ListSelectionListener()
    { public void valueChanged(ListSelectionEvent e) { UpdateButton(); }});
    t5ALScrollPane.setViewportView(t5ALList);
    t5ALPanel.add(t5ALScrollPane,BorderLayout.CENTER);
    t5ALButton.setFont(tFrame.mFont);
    t5ALButton.setText("Добавить");
    t5ALButton.setFocusable(false);
    t5ALButton.setEnabled(false);
    t5ALButton.addActionListener(new ActionListener()
    { public void actionPerformed(ActionEvent e) { int i,j,k,q,n;
      ArrayList al,ta; boolean t=false,before,after;
      n=t5ATList.getSelectedIndex();
      if((n>=0)&&(n<alTrainingSelection.size()))
      { before=SelectionEquals(n); al=(ArrayList)alTrainingSelection.get(n);
        q=al.size(); k=t5ALList.getSelectedIndex();
        if((k>=0)&&(k<tFrame.alTerminalList.size()))
        { for(i=0;i<q;++i) if(((Integer)al.get(i)).intValue()==k) t=true; if(!t)
          { al.add(new Integer(k)); q=al.size(); k=q-1; ta = new ArrayList(q);
            for(i=0;i<q;++i) { j=((Integer)al.get(i)).intValue();
              if((j>=0)&&(j<tFrame.alTerminalList.size()))
                ta.add((String)tFrame.alTerminalList.get(j)); else ta.add(""); }
            t5ARList.setListData(ta.toArray()); //UpdateButton();
            after=SelectionEquals(n); if((n>=0)&&(n<RuleArray.length)) {
              if((before)&&(!after))
              { RuleArray[n]=" (!) "+(String)tFrame.alRuleList.get(n);
                ++cec; t5ATList.setListData(RuleArray); setStatus();
                t5ATList.setSelectedIndex(n); t5ATList.ensureIndexIsVisible(n); }
              if((!before)&&(after))
              { RuleArray[n]="     "+(String)tFrame.alRuleList.get(n);
                --cec; t5ATList.setListData(RuleArray); setStatus();
                t5ATList.setSelectedIndex(n); t5ATList.ensureIndexIsVisible(n); } }
              if((k>=0)&&(k<q))
              { t5ARList.setSelectedIndex(k); t5ARList.ensureIndexIsVisible(k); }
          } } } }});
    t5ALPanel.add(t5ALButton,BorderLayout.SOUTH);

    t5ARPanel.setLayout(new BorderLayout());
    t5ARLabel.setFont(tFrame.mFont);
    t5ARLabel.setText("  Функция Выбора:");
    t5ARPanel.add(t5ARLabel,BorderLayout.NORTH);
    t5ARList.setFont(tFrame.mFont);
    t5ARList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    t5ARList.addListSelectionListener(new ListSelectionListener()
    { public void valueChanged(ListSelectionEvent e) { UpdateButton(); }});
    t5ARScrollPane.setViewportView(t5ARList);
    t5ARPanel.add(t5ARScrollPane,BorderLayout.CENTER);
    t5ARButton.setFont(tFrame.mFont);
    t5ARButton.setText("Удалить");
    t5ARButton.setFocusable(false);
    t5ARButton.setEnabled(false);
    t5ARButton.addActionListener(new ActionListener()
    { public void actionPerformed(ActionEvent e) { int i,j,k,q,n;
      ArrayList al,ta; boolean before,after; n=t5ATList.getSelectedIndex();
      if((n>=0)&&(n<alTrainingSelection.size()))
      { before=SelectionEquals(n); al=(ArrayList)alTrainingSelection.get(n);
        q=al.size(); k=t5ARList.getSelectedIndex(); if((k>=0)&&(k<q))
        { al.remove(k); q=al.size(); if(k>=q) k=q-1; ta = new ArrayList(q);
          for(i=0;i<q;++i) { j=((Integer)al.get(i)).intValue();
            if((j>=0)&&(j<tFrame.alTerminalList.size()))
              ta.add((String)tFrame.alTerminalList.get(j)); else ta.add(""); }
          t5ARList.setListData(ta.toArray()); //UpdateButton();
          after=SelectionEquals(n); if((n>=0)&&(n<RuleArray.length)) {
            if((before)&&(!after))
            { RuleArray[n]=" (!) "+(String)tFrame.alRuleList.get(n);
              ++cec; t5ATList.setListData(RuleArray); setStatus();
              t5ATList.setSelectedIndex(n); t5ATList.ensureIndexIsVisible(n); }
            if((!before)&&(after))
            { RuleArray[n]="     "+(String)tFrame.alRuleList.get(n);
              --cec; t5ATList.setListData(RuleArray); setStatus();
              t5ATList.setSelectedIndex(n); t5ATList.ensureIndexIsVisible(n); } }
          if(k>=0)
          { t5ARList.setSelectedIndex(k); t5ARList.ensureIndexIsVisible(k); }
        } } }});
    t5ARPanel.add(t5ARButton,BorderLayout.SOUTH);
  }

  private void UpdateButton()
  { int i,k,q; ArrayList al; boolean r=false,t=false;
    i=t5ATList.getSelectedIndex();
    if((i>=0)&&(i<alTrainingSelection.size()))
    { al=(ArrayList)alTrainingSelection.get(i); q=al.size();
      k=t5ALList.getSelectedIndex(); if((k>=0)&&(k<tFrame.alTerminalList.size()))
      { for(i=0;i<q;++i) if(((Integer)al.get(i)).intValue()==k) t=true;
        if(!t) r=true; } } t5ALButton.setEnabled(r);
    r=false; i=t5ATList.getSelectedIndex();
    if((i>=0)&&(i<alTrainingSelection.size()))
    { al=(ArrayList)alTrainingSelection.get(i); q=al.size();
      k=t5ARList.getSelectedIndex(); if((k>=0)&&(k<q)) r=true;
    } t5ARButton.setEnabled(r); }

  private void Generator()
  { int i,j,k,l,m,n,o,q; ArrayList al,cal,ala,alb; boolean e[],t;
    RuleArray=null;
    alTrainingSelection.clear();
    ec=0; cec=0;
    t5AStatus.setText("  ");
    t5ALButton.setEnabled(false);
    t5ARButton.setEnabled(false);
    t5ATList.setListData(new Object[0]);
    t5ALList.setListData(new Object[0]);
    t5ARList.setListData(new Object[0]);

    t5ALList.setListData(tFrame.alTerminalList.toArray());
    q=tFrame.alSelection.size(); k=q*(100-tFrame.sk)/100; //Коэффициент
    al = new ArrayList(q); e = new boolean[q];
    for(i=0;i<q;++i) { al.add(new Integer(i)); e[i]=false; }
    for(i=0;i<k;++i) { j=al.size(); if(j>0) { l=(0xffffff&rnd.nextInt())%j;
      m=((Integer)al.get(l)).intValue(); al.remove(l); e[m]=true; } }
    for(i=0;i<q;++i) { al=(ArrayList)tFrame.alSelection.get(i); k=al.size();
      cal = new ArrayList(k); alTrainingSelection.add(cal); if(e[i]) {
        //Получаю список входящих терминалов - ala, не входящих - alb.
        ala = new ArrayList(k);
        for(j=0;j<k;++j) ala.add(new Integer(((Integer)al.get(j)).intValue()));
        m=tFrame.alTerminalList.size(); alb = new ArrayList(m);
        for(l=0;l<m;++l) { t=false; for(j=0;j<k;++j)
          if(((Integer)al.get(j)).intValue()==l) t=true;
            if(!t) alb.add(new Integer(l)); }
        //Получил список входящих терминалов - ala, не входящих - alb.
        j=k+4; if(j>m) j=m; ++j; n=(0xffffff&rnd.nextInt())%j; //Коэффициент
        for(j=0;j<n;++j)
        { l=-1; o=ala.size(); if(o>0) l=(0xffffff&rnd.nextInt())%o;
          m=-1; o=alb.size(); if(o>0) m=(0xffffff&rnd.nextInt())%o;
          if((l>=0)&&(m<0)) { o=((Integer)ala.get(l)).intValue(); ala.remove(l);
            cal.add(new Integer(o)); }
          else if((l<0)&&(m>=0)) { o=((Integer)alb.get(m)).intValue(); alb.remove(m);
            cal.add(new Integer(o)); }
          else if((l>=0)&&(m>=0))
          { if((0xffffff&rnd.nextInt())%2==0) //Коэффициент
            { o=((Integer)alb.get(m)).intValue(); alb.remove(m); }
            else { o=((Integer)ala.get(l)).intValue(); ala.remove(l); }
            cal.add(new Integer(o)); } }

      } else for(j=0;j<k;++j) cal.add(new Integer(((Integer)al.get(j)).intValue())); }

    q=tFrame.alRuleList.size(); RuleArray = new String[q];
    for(i=0;i<q;++i) { if(SelectionEquals(i))
      RuleArray[i]="     "+(String)tFrame.alRuleList.get(i);
      else { RuleArray[i]=" (!) "+(String)tFrame.alRuleList.get(i); ++ec; } }
    t5ATList.setListData(RuleArray); cec=ec; setStatus(); }

  private void setStatus()
  { t5AStatus.setText("  Количество Ошибок: Было - "+ec+", Сейчас - "+cec); }

  private boolean SelectionEquals(int i)
  { boolean r=true,t; int j,k;
    int a,b; ArrayList ala,alb; int ia[],ib[];
    a=tFrame.alSelection.size(); b=alTrainingSelection.size();
    if((i>=0)&&(i<a)) ala=(ArrayList)tFrame.alSelection.get(i);
    else ala = new ArrayList(0);
    if((i>=0)&&(i<b)) alb=(ArrayList)alTrainingSelection.get(i);
    else alb = new ArrayList(0);
    a=ala.size(); ia = new int[a];
    for(j=0;j<a;++j) ia[j]=((Integer)ala.get(j)).intValue();
    b=alb.size(); ib = new int[b];
    for(j=0;j<b;++j) ib[j]=((Integer)alb.get(j)).intValue();
    for(j=0;j<a;++j)
    { t=false; for(k=0;k<b;++k) if(ia[j]==ib[k]) t=true;
      if(!t) r=false; }
    for(j=0;j<b;++j)
    { t=false; for(k=0;k<a;++k) if(ib[j]==ia[k]) t=true;
      if(!t) r=false; }
    return(r); }

  public boolean tClose()
  {
    tFrame.mMenuBar.removeAll();
    tFrame.mToolBar.removeAll();
    tFrame.mSplitPane.setBottomComponent(null);
    RuleArray=null;
    alTrainingSelection.clear();
    ec=0; cec=0;
    t5AStatus.setText("  ");
    t5ALButton.setEnabled(false);
    t5ARButton.setEnabled(false);
    t5ATList.setListData(new Object[0]);
    t5ALList.setListData(new Object[0]);
    t5ARList.setListData(new Object[0]);
    tFrame.validate();
    return(true); }

  public void tOpen()
  {
    tFrame.mSplitPane.setBottomComponent(t5APanel);
    Generator();
    JMenu jMenu;
    jMenu = new JMenu("File");
    jMenu.setMnemonic(KeyEvent.VK_F);
    tFrame.mMenuBar.add(jMenu);
    jMenu.add(aFileGenerateFunctions).setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_G,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("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(aFileGenerateFunctions);
    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.validate();
  }
}
