/**
 * 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 3 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, see <http://www.gnu.org/licenses/>.
 
 * Copyright Tim Hutton and Berlin Brown <berlin dot brown at gmail.com> 2011
 * Copyright Berlin Brown 2012 modifications
 *  
 * Tim Hutton is the original author, but a license not provided in source,
 * GPL was used for similar projects.  If Tim or anyone else has questions, please contact Berlin Brown.
 
 * http://www.sq3.org.uk/Evolution/Squirm3/
 
 * Squirm3 is an artificial chemistry simulation 
 */
package org.berlin.chem.gae;

import java.util.Stack;
import java.util.Vector;
import java.util.logging.Logger;

import org.berlin.chem.gae.web.DBFrame;

/**
 * Main Class for JFrame Squirm Java Graphics Component.
 * Stateless.
 */
public class DBSquirm extends DBFrame {

    private static final long serialVersionUID = 1L;

    private static final Logger LOGGER = Logger.getLogger(DBSquirm.class.getCanonicalName());
               
    /**
     * Squirm Class Constructor
     */
    public DBSquirm(final Vector<DBSquirmCell> cellListDatabase, final Stack<String> recordDatabase) {
        super(cellListDatabase, recordDatabase);       
    // End of the constructor //
    
    public void removeAllReactions(final DBSquirmChemistry chemistry) {
        chemistry.removeAllReactions();        
    }

    /**
     * The init() method is called by the AWT when an applet is first loaded or
     * reloaded.
     */
    public void initSquirmChem(final DBSquirmChemistry chemistry, final int typeOfChemistryAllowed) {
        removeAllReactions(chemistry);
        // which reaction-set do you want?
        final int typeOfReactionAllowedEditableFromSrc = typeOfChemistryAllowed;
        switch (typeOfReactionAllowedEditableFromSrc) {
        case 0{
            // new slimline replication reactions (for: e8-a1-b1-...-f1)
            addReaction(chemistry, "e"8, false, "e"04, true, 3)// R1
            addReaction(chemistry, "x"4, true, "y"12, true, 5)// R2
            addReaction(chemistry, "x"5, false, "x"07, true, 6)// R3
            addReaction(chemistry, "x"3, false, "y"62, true, 3)// R4
            addReaction(chemistry, "x"7, true, "y"34, true, 3)// R5
            addReaction(chemistry, "f"4, true, "f"38, false, 8)// R6
            addReaction(chemistry, "x"2, true, "y"89, true, 1)// R7
            addReaction(chemistry, "x"9, true, "y"98, false, 8)// R8
            break;
        }
        case 1{
            // genes as instructions (for: e1-a1-b1-...-f1)
            addReaction(chemistry, "e"1, false, "e"04, true, 3)// R1
            addReaction(chemistry, "x"4, true, "y"12, true, 5)// R2
            addReaction(chemistry, "x"5, false, "x"07, true, 6)// R3
            addReaction(chemistry, "x"3, false, "y"62, true, 3)// R4
            addReaction(chemistry, "x"7, true, "y"34, true, 3)// R5
            addReaction(chemistry, "f"4, true, "f"38, false, 8)// R6
            addReaction(chemistry, "x"2, true, "y"89, true, 10)// R7
            addReaction(chemistry, "x"9, true, "y"98, false, 8)// R8

            addReaction(chemistry, "f"10, true, "x"101, true, 11)// R9
            addReaction(chemistry, "x"12, true, "y"101, true, 11)// R10
            addReaction(chemistry, "e"8, true, "x"121, true, 1)// R11

            // some catalysing reactions to try
            addReaction(chemistry, "a"11, false, "b"012, false, 1)// R12?
            addReaction(chemistry, "b"11, false, "a"012, false, 0)// R13?
            addReaction(chemistry, "c"11, false, "d"012, false, 0)// R14?
            addReaction(chemistry, "d"11, false, "d"012, false, 0)// R15?
            break;
        }
        case 5{
            // Variant 5 replication reactions
            // -- the reactions for self-replicating strings --
            addReaction(chemistry, "e"1, false, "e"04, true, 10)// R1
            addReaction(chemistry, "x"4, true, "y"12, true, 5)// R2
            addReaction(chemistry, "x"5, false, "x"07, true, 6)// R3
            addReaction(chemistry, "x"10, false, "y"63, true, 10)// R4
            addReaction(chemistry, "x"7, true, "y"104, true, 10)// R5
            addReaction(chemistry, "f"4, true, "f"108, false, 8)// R6
            addReaction(chemistry, "x"2, true, "y"89, true, 1)// R7
            addReaction(chemistry, "x"3, true, "y"89, true, 1)// R8
            addReaction(chemistry, "x"9, true, "y"98, false, 8)// R9
            addReaction(chemistry, "e"8, true, "x"11, true, 1)// R10
            break;
        }
        case 9{
            // Variant 9 replication and membrane reactions
            // pre-duplication hurdles (to slow things down)
            addReaction(chemistry, "e"1, false, "d"037, false, 0);
            addReaction(chemistry, "e"37, false, "c"038, false, 0);
            // start of duplication
            addReaction(chemistry, "e"38, false, "a"115, true, 10)// R8 // was 4,
            // not 11 (slows
            // down+tidies)
            addReaction(chemistry, "a"10, true, "a"410, true, 11)// R9
            addReaction(chemistry, "a"11, false, "e"613, true, 3)// R10
            // mid-duplication
            addReaction(chemistry, "x"4, true, "y"12, true, 5)// R1
            addReaction(chemistry, "x"5, false, "x"07, true, 6)// R2
            addReaction(chemistry, "x"3, false, "y"62, true, 3)// R3
            addReaction(chemistry, "x"7, true, "x"34, true, 3)// R4
            // start of splitting
            addReaction(chemistry, "f"4, false, "a"48, true, 10)// R7a
            addReaction(chemistry, "f"3, false, "a"118, false, 12)// R7b
            // mid-splitting
            addReaction(chemistry, "x"8, true, "y"89, false, 9)// R5
            addReaction(chemistry, "x"9, true, "y"21, true, 8)// R6

            // start of pulling
            addReaction(chemistry, "a"10, true, "f"119, true, 12)// R18
            addReaction(chemistry, "a"12, false, "f"1120, true, 21)// R19
            addReaction(chemistry, "a"19, true, "f"2119, true, 11)// R20
            addReaction(chemistry, "a"20, false, "x"1315, true, 14)// R21
            // mid-pulling
            addReaction(chemistry, "x"12, true, "y"111, true, 13)// R12
            addReaction(chemistry, "a"9, false, "x"1315, true, 14)// R13
            addReaction(chemistry, "a"15, true, "x"1116, false, 17)// R14
            addReaction(chemistry, "a"16, true, "x"149, true, 12)// R15
            addReaction(chemistry, "x"17, true, "y"111, true, 11)// R16
            // end of pulling
            addReaction(chemistry, "x"12, true, "e"911, true, 13)// R17

            // membranes join
            addReaction(chemistry, "a"15, true, "e"1222, false, 13)// R23
            addReaction(chemistry, "a"22, true, "a"1922, true, 25)// R23b
            addReaction(chemistry, "a"25, true, "f"126, false, 1)// R23c
            addReaction(chemistry, "a"26, false, "a"1024, true, 23)// R24

            // membranes separate
            addReaction(chemistry, "a"22, true, "a"2411, false, 4)// R25 // tried
            // with 11 here
            // instead of 4
            addReaction(chemistry, "a"14, true, "a"2327, false, 28)// R26

            // gene-strings are released into their new membranes
            addReaction(chemistry, "a"27, true, "e"94, false, 1)// R27
            addReaction(chemistry, "a"28, true, "e"1330, false, 29)// R28
            addReaction(chemistry, "e"29, true, "x"171, true, 1)// R29
            addReaction(chemistry, "a"30, true, "a"114, true, 4)// R31

            // synthesis of a31's through contact of a0 with x1 or x2 (pretty
            // liberal)
            addReaction(chemistry, "x"1, false, "a"01, false, 31)// R32
            addReaction(chemistry, "x"2, false, "a"02, false, 31)// R32b

            // membrane growth
            addReaction(chemistry, "a"4, false, "a"3133, true, 32)// R33
            addReaction(chemistry, "a"33, true, "a"434, true, 35)// R34
            addReaction(chemistry, "a"35, false, "a"3236, true, 4)// R35
            addReaction(chemistry, "a"36, true, "a"344, false, 4)// R36
            break;
        }
        }

    // End of the method //
    
    protected void addReaction(final DBSquirmChemistry chemistry, final String us_type, int us_state, boolean current_bond, String them_type, int them_state, int future_us_state,
            boolean future_bond, int future_them_state) {

        final DBModelSquirmReaction r = new DBModelSquirmReaction(us_type.toCharArray()[0], us_state, current_bond, them_type.toCharArray()[0], them_state,
                future_us_state, future_bond, future_them_state);
        chemistry.addReaction(r);
        // DEBUG: show each received reaction
        final String msg = us_type + us_state + (current_bond ? "-" " "+ them_type + them_state + " => " + us_type + future_us_state
                (future_bond ? "-" " "+ them_type + future_them_state + "; ";     
        final String addReaction = msg;
        LOGGER.info("Adding reaction allowed on the grid (init) : " + addReaction);
    }

// End of the class //