import * as React from 'react';
import { Box, Grid, TextField, Button, Table, TableHead, TableRow, TableBody, ExpansionPanel, ExpansionPanelSummary, Typography, ExpansionPanelDetails, TableCell, Container } from '@material-ui/core';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import { chosenAlphabet, passwordLoad, inputLoad, writerToOutput, regexp, myAlert } from '../../basicLayout';

export interface IPasswordCipherProps {
    idInput: string,
    idOutput: string,
    idSwitch: string
}

export interface IPasswordCipherState {
    passwordOutput: string
}

export default class PasswordCipher extends React.Component<IPasswordCipherProps, IPasswordCipherState> {
    constructor(props: IPasswordCipherProps) {
        super(props);

        this.state = {
            passwordOutput: ""
        }
    }

    public makeCipherAlphabet(oldAlphabetArray: string[], password: string): string[] {
        var newAlphabet: string = '';
        var arrayPassword: string[] = password.split('');

        arrayPassword.forEach(element => {
            if (!newAlphabet.includes(element))
                newAlphabet += element;
        });

        oldAlphabetArray.forEach(element => {
            if (!newAlphabet.includes(element))
                newAlphabet += element;
        })

        return newAlphabet.split('');
    }

    private PasswordCipher(password: string, decrypt: boolean): string {
        // PASSWORD & INPUT LOAD
        var message: string[] = inputLoad().split('');
        var ciphertext: string = '';

        // DETERMINATION OF THE USED ALPHABET
        var messageAlphabet: string[];
        var cipherAlphabet: string[];
        if (decrypt) {
            messageAlphabet = this.makeCipherAlphabet(chosenAlphabet, password);
            cipherAlphabet = chosenAlphabet;
        }
        else {
            messageAlphabet = chosenAlphabet;
            cipherAlphabet = this.makeCipherAlphabet(chosenAlphabet, password);
        }

        // PASSWORD-MODIFIED CIPHER
        message.forEach( e => {
            var upperCase: boolean = false;
            if (e.match(regexp)) {
                if (e === e.toUpperCase()) {
                    e = e.toLowerCase();
                    upperCase = true;
                }

                if (upperCase)
                    ciphertext += cipherAlphabet[messageAlphabet.indexOf(e.toLocaleLowerCase())].toUpperCase();
                else
                    ciphertext += cipherAlphabet[messageAlphabet.indexOf(e.toLocaleLowerCase())];
            }
            else
                ciphertext += e;
        });

        return ciphertext;
    }

    public render() {
        var password: string = passwordLoad("passwordPassword").toLowerCase();
        var row: string[] = this.makeCipherAlphabet(chosenAlphabet, password);
        const tableCellsAlphabet = chosenAlphabet.map( e =>
            <TableCell key={e} align="center" component="th" scope="row" style={{ padding: 3 }}>
                {e}
            </TableCell>
        );
        const tableCellsMovedAlphabet = row.map((e: any) =>
            <TableCell key={e} align="center" component="th" scope="row" style={{ padding: 3 }}>
                {e}
            </TableCell>
        );

        return (
            <div>
                <Grid container className='rowGrid'>
                    <Box my={2}>
                        <TextField
                            required
                            id="passwordPassword"
                            label="Password"
                            defaultValue='SECRET'
                            helperText="Password used for alphabet modification."
                            InputLabelProps={{
                                shrink: true,
                            }}
                            onChange={ () => {
                                this.forceUpdate();
                            }}
                            className='smallTextField'
                        />
                    </Box>
                    <Container>
                        <Button
                            size="large"
                            variant="contained"
                            color="secondary"
                            autoFocus
                            onClick={ () => {
                                this.forceUpdate();
                                if ((document.getElementById("passwordPassword") as HTMLInputElement).value === '') {
                                    var tmp = myAlert("Password isn't defined! Please define the password:", 'enter', ['secret']);
                                    if( tmp != null)
                                        (document.getElementById("passwordPassword") as HTMLInputElement).value = String(tmp);
                                    else
                                        return;
                                }

                                var decrypt: boolean = false;
                                if((document.getElementById(this.props.idSwitch) as HTMLInputElement).checked)
                                    decrypt = true;
                                
                                writerToOutput(this.PasswordCipher(passwordLoad("passwordPassword").toLowerCase(), decrypt));
                            }}
                            className="monoButton"
                        >Cipher go!</Button>
                    </Container>
                </Grid>

                <Box my={5} boxShadow={3}>
                    <Table className="table">
                        <TableHead>
                            <TableRow>
                                {tableCellsAlphabet}
                            </TableRow>
                        </TableHead>
                        <TableBody>
                            <TableRow>
                                {tableCellsMovedAlphabet}
                            </TableRow>
                        </TableBody>
                    </Table>
                </Box>

                <Box marginTop={10}>
                    <ExpansionPanel>
                        <ExpansionPanelSummary
                            id="aboutPasswordCipher"
                            expandIcon={<ExpandMoreIcon />}
                        >
                            <Typography
                                color="secondary"
                                className='heading'
                            ><b>ABOUT Keyword Cipher</b></Typography>
                        </ExpansionPanelSummary>
                        <ExpansionPanelDetails>
                            <Grid container className='columnGrid'>
                                <Typography style={{ color: '#808080' }} align='left' component={"div"}>
                                    <p>
                                        <b>Keyword cipher</b> is a simple <i>monoalphabetic substitution cipher </i> 
                                        that uses password composited from letters to modify substituing alphabet.
                                    </p>
                                </Typography>
                                
                                <Grid container className='columnGrid'>
                                    <img
                                        src="http://www.stud.feec.vutbr.cz/~xrysav29/cipher_pics/password_alphabet.PNG"
                                        alt='Keyword cipher - alphabet modification'
                                        width="50%"/>
                                </Grid>
                                <Typography variant='caption' style={{ color: '#808080' }} align='center'>
                                    <b>Img 1.:</b> <i>Alphabet modification with password.</i>
                                </Typography>

                                <Typography style={{ color: '#808080' }} align='left' component={"div"}>
                                    <p>
                                        Modification of the substituing alphabet is achieved by asserting chosen password
                                        on the beginning of the "normal" alphabet and then removing all multiples of each letter
                                        beginnig from the start of the alphabet. The process of encryption and decryption using this cipher is then 
                                        same as in case of Ceasar cipher.
                                    </p>
                                </Typography>

                                <Grid container className='columnGrid'>
                                    <img
                                        src="http://www.stud.feec.vutbr.cz/~xrysav29/cipher_pics/password_encryption.PNG"
                                        alt='Keyword cipher encryption'
                                        width="60%"/>
                                </Grid>
                                <Typography variant='caption' style={{ color: '#808080' }} align='center'>
                                    <b>Img 2.:</b> <i>Encryption of plaintext using created alphabet.</i>
                                </Typography>
                            </Grid>
                        </ExpansionPanelDetails>
                    </ExpansionPanel>
                </Box>
            </div>
        );
    }
}