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

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

export interface IVernamCipherState {
    vernamOutput: string
}

export default class VernamCipher extends React.Component<IVernamCipherProps, IVernamCipherState> {
    private history: boolean = true;
    private numberList: number = 0;
    private formatedList: any = '';
    private list: any[] = [];
    constructor(props: IVernamCipherProps) {
        super(props);

        this.state = {
            vernamOutput: ''
        }
    }

    private VernamCipher() {
        var input: string[] = inputLoad().split('');
        var usedKey: number[] = [];
        var counter = 0;
        var message: string = '';

        if((document.getElementById('keyField') as HTMLInputElement).value !== '') {
            var tmpArray: string[] = (document.getElementById('keyField') as HTMLInputElement).value.split(',');
            var i = 0;
            tmpArray.forEach( e => {
                if(e.match(/\d/))
                    usedKey[i++] = Number(e);
                else {
                    myAlert('There are diffrent characters from numbers in the custom key field!', 'info');
                    usedKey = [];
                }
            });
        }

        input.forEach( e => {
            var upperCase = false;
            if(e.match(regexp)) {
                if (e === e.toUpperCase()) {
                    upperCase = true;
                    e = e.toLowerCase();
                }
                
                if(usedKey[counter] === undefined)
                    usedKey[counter] = Math.round(Math.random() * (chosenAlphabet.length-1));

                var key: number = 0;
                if ((document.getElementById(this.props.idSwitch) as HTMLInputElement).checked)
                    key = -usedKey[counter];
                else
                    key = usedKey[counter] 

                var tmpAlphabet = new CaesarCipher(this.props).alphabetMove(key);
                
                e = tmpAlphabet[chosenAlphabet.indexOf(e)];
    
                if (upperCase)
                    e = e.toUpperCase();
                
                counter++;
            }
            message += e;
        });

        (document.getElementById('usedPswdField') as HTMLInputElement).innerHTML = String(usedKey);
        (document.getElementById('keyField') as HTMLInputElement).value = '';

        var joinKey = usedKey.join(', ');
        if(this.list.indexOf(joinKey) === -1) {
            this.list[this.numberList] = joinKey;
            this.formatedList += '(('+ ((this.numberList++) + 1) + '.)) ' + joinKey + '\n';
        }

        return { message, usedKey };
    }

    public render() {
    return (
        <div>
            <Typography variant='overline' style={{ color: '#808080' }} align='left' component={"div"}>
                Used password:
            </Typography>
            <TextField
              id="usedPswdField"
              fullWidth
              multiline
              rowsMax="2"
              placeholder='Run the cipher for password to appear.'
              className='textField'
              InputProps={{
                readOnly: true,
              }}
            />
            <Typography id='usedPswdField' color='primary' align='center' className='text' gutterBottom></Typography>

            <Box my={2}>
                <Typography variant='overline' color='primary' align='left' component={"div"}>
                    Custom password:
                </Typography>
                <TextField
                    id="keyField"
                    fullWidth
                    multiline
                    rowsMax="2"
                    placeholder='21,4,7,15,3, ...'
                    helperText="Field for custom password (otherwise auto generated)"
                    InputLabelProps={{
                        shrink: true,
                    }}
                />
            </Box>

            <Container>
                <Button
                    size="large"
                    variant="contained"
                    color="primary"
                    autoFocus
                    onClick={ () => {
                        this.forceUpdate();
                        var tmp = this.VernamCipher();
                        writerToOutput(tmp.message);
                        this.history = false;
                        if(!(document.getElementById(this.props.idSwitch) as HTMLInputElement).checked) {
                            (document.getElementById('historyTypo') as HTMLElement).innerText = this.formatedList;
                        }
                    }}
                >Vernam go!</Button>
            </Container>

            <Box marginTop={2} hidden={this.history}>
                <ExpansionPanel>
                <ExpansionPanelSummary
                    id="keysHistoryPanel"
                    expandIcon={<ExpandMoreIcon />}
                >
                    <Typography
                    style={{ color: '#73c2fb' }}
                    className='heading'
                    ><i>History of used keys</i></Typography>
                </ExpansionPanelSummary>
                <ExpansionPanelDetails>
                    <Typography id="historyTypo" style={{ color: '#808080' }} align='left' component={"div"}/>
                </ExpansionPanelDetails>
                </ExpansionPanel>
            </Box>

            <Box marginTop={10}>
                <ExpansionPanel>
                    <ExpansionPanelSummary
                        id="aboutVernamCipher"
                        expandIcon={<ExpandMoreIcon />}
                    >
                        <Typography
                            color="primary"
                            className='heading'
                        ><b>ABOUT Vernam cipher</b></Typography>
                    </ExpansionPanelSummary>
                    <ExpansionPanelDetails>
                        <Grid container className='columnGrid'>
                            <Typography style={{ color: '#808080' }} align='left' component={"div"}>                            
                                <p>
                                    <b>Vernam cipher</b>, (also <i>one-time pad</i>) is a special type of <i>polyalphabetic substitution cipher</i>. 
                                    This cipher uses Caesar cipher with different key for each letter. Such 'key-chain' is usually generated by RNG ('
                                    <Link color='primary' href='https://en.wikipedia.org/wiki/Random_number_generation' target="_blank" rel="noopener noreferrer"><i>Random Number Generator</i></Link>
                                    ' - program or machine generating values that can't be resonably predicted).
                                </p>
                            </Typography>

                            <Grid container className='columnGrid'>
                                <img
                                    src="http://www.stud.feec.vutbr.cz/~xrysav29/cipher_pics/vernam_encryption.PNG"
                                    alt='Vernam encryption'
                                    width="80%"/>
                            </Grid>
                            <Typography variant='caption' style={{ color: '#808080' }} align='center'>
                                <b>Img 1.:</b> <i>Encryption of plaintext using Vernam cipher.</i>
                            </Typography>
                        
                            <Typography style={{ color: '#808080' }} align='left' component={"div"}>
                                <p>
                                    Since this cipher uses different key for each element of the message this cipher is impossible to break, only if one has 
                                    the used key (<u>NOTE:</u> brute-force will genrate <b>all</b> possible answers - including those, that make sense but are not correct).
                                </p>
                            </Typography>
                        </Grid>
                    </ExpansionPanelDetails>
                </ExpansionPanel>
            </Box>
        </div>
    );
    }
}