/**
  *
  * description
  *
  * @version 1.0 from 15.01.2016
  * @author 
  */

import java.io.IOException;
import java.math.BigInteger;
import java.util.Random;
import java.awt.Graphics;
 import java.awt.image.BufferedImage;
 import java.io.IOException;
 import java.net.URL;
 import javax.imageio.ImageIO;
 import javax.swing.*;
 import java.util.*;
  import java.awt.FontMetrics;

public class Key {

  // Anfang Attribute
  private String name;
  private BigInteger n;
  private BigInteger e;
  private int BLOCKSIZE;
  private BufferedImage image;
  private String filename;
  private byte[] hashCode;
  // Ende Attribute
  
  public Key(String name, BigInteger e, BigInteger n) {
    this.name = name;
    this.n = n;
    this.e = e;
    this.image = image;
    this.hashCode = null;
    calcBlocksize();
  }
  
  // Anfang Methoden
  public String getName() {
    return name;
  }
  
  public void setName(String name) {
    this.name = name;
  }
  
  public BigInteger getN() {
    return n;
  }
  
  public BigInteger getE() {
    return e;
  }
  
  public void setImage(String filename) {
    URL pic_url = this.getClass().getClassLoader().getResource(filename+".png"); //kein Slash vor dem Unterordner!
    this.filename = filename;
    //Bild laden mit ImageIO
    try {
      image = ImageIO.read(pic_url);
    } catch (IOException e) {
      e.printStackTrace();
    }
    
    
  }
  
  public String getFilename() {
    return filename;
  }
    
  public BufferedImage getImage() {
    return image;
  }
  
  private BigInteger convert(String text) {
    BigInteger i = BigInteger.valueOf(0);
    for(int j =0; j < text.length(); j++) { 
      i = i.multiply(BigInteger.valueOf(256));
      i = i.add(BigInteger.valueOf((int) text.charAt(j)));
    } // end of while
    // System.out.println(text+" in "+i.toString()+" umgewandelt.");
    return i;
  }
  
  public BigInteger convert(byte[] text) {
    BigInteger i = BigInteger.valueOf(0);
    for(int j =text.length-1; j >=0; j--) { 
      i = i.multiply(BigInteger.valueOf(256));
      int unsingedByte = ((int)text[j]) & 0xFF;
      //      System.out.println(""+unsingedByte+" ");
      i = i.add(BigInteger.valueOf(unsingedByte));
    } // end of while
    //    System.out.println("");
    // System.out.println(new String(text)+" in "+i.toString()+" umgewandelt.");
    return i;
  }
  
  /*  private String convert(BigInteger i) {
    String text = "";
    int j = 0;
    while (text.length()<BLOCKSIZE) { 
      j = i.mod(BigInteger.valueOf(256)).intValue();
      i = i.divide(BigInteger.valueOf(256));
      text = (char) j+text;
    } // end of while
    //System.out.println(i.toString()+" in "+text+" umgewandelt.");
    return text;
  } */
  
  public byte[] convert(BigInteger i) {
    byte[] text = new byte[BLOCKSIZE];
    int j = 0;
    int x = 0;
    while (!i.equals(BigInteger.ZERO)) { 
      j = i.mod(BigInteger.valueOf(256)).intValue();
      i = i.divide(BigInteger.valueOf(256));
      text[x] = (byte) j;
      x++;
    } // end of while
    //System.out.println(i.toString()+" in "+text+" umgewandelt.");
    byte[] a3 = new byte[x];
    System.arraycopy(text, 0, a3, 0, x);
    return a3;
  }
  
  public int calcBlocksize() {
    BigInteger bs = BigInteger.valueOf(1);
    int size = 1;
    while (bs.compareTo(n)<0) {
      bs = bs.multiply(BigInteger.valueOf(256));
      size++;
    }
    BLOCKSIZE = size-1;
    //System.out.println(size-1);
    return BLOCKSIZE;
  }
  
  public String encrypt(String text) {
    String kr = "";
    BigInteger i;
    i = convert(text);
    i = i.modPow(e, n);
    //System.out.println(i);
    kr = kr+ convert(i);
    return kr;
  }
  
  public BigInteger encrypt(BigInteger i) {
    i = i.modPow(e, n);
    
    return i;
  }
  
  public byte[] encrypt(byte[] text) {
    byte[] kr;
    BigInteger i;
    i = convert(text);
    i = i.modPow(e, n);
    //   System.out.println(i);
    kr = convert(i);
    return kr;
  }
  
  public String toString(String name) {
    return "Key:Name="+name+",E="+getE()+",N="+getN();
  }
    
  
  public void sign(Key k, String name) {
    Nachricht dummy = new Nachricht("dummy","dummy",toString(name));
    dummy.generateHash();
    byte[] b = dummy.getHashCode();
    hashCode = k.encrypt(b);
  }

  public boolean isSigned() {
    return hashCode!=null;
  }
    
  public byte[] getHashCode() {
      return hashCode;
    }



// Ende Methoden

}
