import DrawIcon from './tokenIcon';
import stringFunctions, {isAddress} from './utils';
import QRCode from 'qrcode';


/**
 * Main plugin logic
 */
class EtheriumQRplugin {
    /**
     * 
     * Draws QR code to canvas tag inside specific DOM selector
     *
     * @public 
     * @param {Object} config 
     * @returns void
     */
    toCanvas(config) {
        if (!config.selector) {
            this.result.status = 'error';
            this.result.value = 'The canvas element parent selector is required when calling `toCanvas`';
            throw new Error('The canvas element parent selector is required when calling `toCanvas`');
        }
        this.generate(config).then(function (qrCodeDataUri) {
            let canvas = document.createElement('canvas');
            const canvasContainer = document.querySelector(config.selector);
            canvasContainer.appendChild(canvas);
            var ctx = canvas.getContext('2d');
            var img = new Image;
            img.onload = function(){
                ctx.drawImage(img,0,0);
            };
            img.src = qrCodeDataUri;
        })
    }
    /**
     * 
     * Returns a QR code generation promise
     * 
     * @public
     * @param {Object} config 
     * @returns Promise
     */
    toDataUrl(config) {
        return this.generate(config)
    }

    generate(config) {
        this.parseRequest(config);
        const generatedValue = this.produceEncodedValue();
        
        this.result.status = 'success';
        this.result.value = generatedValue;

        return new Promise((resolve, reject) => {
            QRCode.toDataURL(generatedValue, this.options, function (err, url) {
                if (err) reject(err);
                resolve(url)
            })
        });
    }
    produceEncodedValue(){
        let generatedCode = this.schemaGenerator(this.to,
                                                this.gas,
                                                this.value,
                                                this.functionSignature,
                                                this.functionArguments);
        const jsonRepresentation = {
            to: this.to,
            gas: this.gas,
            value: this.value,
            functionSignature: this.functionSignature,
            functionArguments: this.functionArguments
        };
        return this.toJSON ? JSON.stringify(jsonRepresentation) : generatedCode;
    }
    parseRequest(request) {
        this.result = {
            status: ''
        };

        if (!request.to || !isAddress(request.to)) {
            this.result.status = 'error';
            this.result.value = 'The "to" parameter with a valid Etherium adress is required';
            throw new Error('The "to" parameter with a valid Etherium adress is required');
        }

        if (request.mode) {
            if (request.mode === 'function' && request.functionSignature && request.functionArguments) {
                this.mode = 'function';
                this.functionSignature = request.functionSignature;
                this.functionArguments = request.functionArguments;
            } else if (request.mode === 'erc20' && request.from) {
                this.mode = 'erc20';
            } else {
                this.mode = 'eth';    
            }
        } else {
            this.mode = 'eth';
        }

        //todo use Object.assign
        this.to = request.to;
        this.from = request.from;
        this.value = parseFloat(request.value) || 0;
        this.gas = parseFloat(request.gas) || 10000;
        this.toJSON = request.toJSON ? request.toJSON === 'true' : false;
        this.size = request.size || 128;
        this.imgUrl = request.imgUrl || false;
        this.options = {
            color: {
                dark: '#000000',
                light: '#ffffff'
            },
            scale: 4
        };
        this.schemaGenerator = stringFunctions[this.mode];
    }
    drawTokenIcon() {
        if (this.imgUrl) {
            const iconDraw = new DrawIcon();
            iconDraw.addIcon(this.imgUrl, this.size, this.uiElement, () => {
                this.uiElement.parentNode.removeChild(this.uiElement);
            });
        }
    }
}

export default EtheriumQRplugin;
@@ -364,207 +364,244 @@
     
-if (!config.selector) %7B%0A            this.result.status = 'error';%0A            this.result.value = 'The canvas element parent selector is required when calling %60toCanvas%60';%0A            throw new Error
+this.parseRequest(config);%0A        const generatedValue = this.produceEncodedValue();%0A        const parentEl = document.querySelector(config.selector);%0A%0A        if (!config.selector %7C%7C parentEl === null) %7B%0A            this.errorCallback
 ('Th
@@ -682,24 +682,25 @@
       %7D%0A
+%0A
         
 this.gen
@@ -695,195 +695,215 @@
     
-this.generate(config).then(function (qrCodeDataUri) %7B%0A            let canvas = document.createElement('canvas');%0A            const canvasContainer = document.querySelector(config.selector
+return new Promise((resolve, reject) =%3E %7B%0A             QRCode.toCanvas(generatedValue, this.options, (err, canvas) =%3E %7B%0A                if (err) reject(err);%0A          %0A                resolve(generatedValue
 );%0A 
@@ -917,23 +917,20 @@
     
-canvasContainer
+    parentEl
 .app
@@ -963,25 +963,19 @@
     
-var ctx =
+   
  canvas.
 getC
@@ -974,187 +974,119 @@
 vas.
-getContext('2d');%0A            var img = new Image;%0A            img.onload = function()%7B%0A                ctx.drawImage(img,0,0);%0A            %7D;%0A            img.src = qrCodeDataUri;
+setAttribute('style', %60width: $%7Bthis.size%7Dpx%60);%0A                successCallback(generatedValue);%0A            %7D)
 %0A   
@@ -1089,24 +1089,25 @@
 %0A        %7D)%0A
+%0A
     %7D%0A    /*
@@ -1274,75 +1274,8 @@
 ) %7B%0A
-        return this.generate(config)%0A    %7D%0A%0A    generate(config) %7B%0A
     
@@ -1367,101 +1367,8 @@
 e();
-%0A        %0A        this.result.status = 'success';%0A        this.result.value = generatedValue;
 %0A%0A  
@@ -1473,25 +1473,16 @@
 options,
- function
  (err, u
@@ -1484,16 +1484,19 @@
 rr, url)
+ =%3E
  %7B%0A     
@@ -1569,29 +1569,313 @@
         
-%7D)%0A        %7D)
+    this.successCallback(url);%0A            %7D)%0A        %7D);%0A    %7D%0A    errorCallback()%7B%0A        this.result.status = 'error';%0A        this.result.value = value;%0A        throw new Error(value);%0A    %7D%0A    successCallback(value)%7B%0A        this.result.status = 'success';%0A        this.result.value = value
 ;%0A    %7D%0A
@@ -2710,155 +2710,21 @@
 his.
-result.status = 'error';%0A            this.result.value = 'The %22to%22 parameter with a valid Etherium adress is required';%0A            throw new Error
+errorCallback
 ('Th
@@ -3729,16 +3729,30 @@
 tions = 
+Object.assign(
 %7B%0A      
@@ -3870,19 +3870,28 @@
 le: 
-4%0A        %7D
+5%7D, request.options)
 ;%0A  

correct canvas generation, extened options