Code viewer for World: Improving DoodleNet
// Cloned by Cian on 4 Dec 2021 from World "Recognise any image" by Starter user 
// Please leave this clone trail here.



// ML5 image recognition using DoodleNet 
// uses AB framework to run ML5



// no run, pause, step
AB.drawRunControls = false;

let classifier;
let img;

let clearButton;
let canvas;
let doodleClassifier;

// my own model----------------------
let model;





//----------------



// asynchronous loads of resources, with callback functions when ready 
var classifierLoaded = false;
var imgLoaded = false;
var timer = 10;



AB.world.newRun = function () {

    ABWorld.init('white')
    ABWorld.canvas;
    //button = createButton('submit');
    //button.position(input.x + input.width, 65);
    //button.mousePressed(clearCanvas);
    
   
    //AB.headerRHS();   
    // uisng splash screen for clear button
   // AB.newSplash();
   // AB.splashHtml(" <button onclick='clearCanvas();'  class=ab-normbutton >Clear</button> <p> " );

    // DoodleNet load pretrained
    doodleClassifier = ml5.imageClassifier('DoodleNet', modelReady)
    AB.msg('model loading')
    
    // timer attempt to save users input doodle as jpg for futre models
    if(timer === 0){
        saveCanvas(ABWorld.p5canvas, 'myCanvas', 'jpg');
    }
    
    //---------------------------
    // ABWorld.p5canvas will be passed to model
    // Custom Model from Teachable Machine
   //  myClassifier = ml5.imageClassifier('path/to/custom/model.json', modelReady);
   
    // custom model attenmpt
    shapeClassifier = ml5.neuralNetwork(options);
    const modelDetails = {
        model: 'model/model.json',
        metadata: 'model/model_meta.json',
        weights: 'model/model.weights.bin',
  };
    shapeClassifier.load(modelDetails, modelLoaded);
    
    //-------------------------


    function modelReady() {
        console.log('model loaded');
        // generate results
        doodleClassifier.classify(ABWorld.p5canvas, gotResults);
    }
    // --- keyboard and touch handling functions: ----------------------------------------

    // keyCode attempt, used to detect special keys, also tested regulat 'key'
    function keyPressed() {
        if (keyCode === SHIFT) {
         saveCanvas(ABWorld.p5canvas, 'myCanvas', 'jpg'); // save canvas
        }
    }
    
    // results----------------------------------------- could use AB.newDiv(id) rather than AB.msg https://ancientbrain.com/docs.ab.php
    AB.headerRHS();   
    AB.msg ( "Running image recognition ... <br> ", 1 );
    AB.runReady = true;
    
    
    function gotResults(error, results){
        if (error){ 
            console.log(error);
            AB.msg ( "<font color=red> <B> Error recognising doodle. See console for details. </b></font> <br> ", 2 );
            return;
        }
    // display top 2 results
    let content = ` ${results[0].label} 
                    ${nf(100 * results[0].confidence, 2, 1)}%<br/>
                    ${results[1].label} 
                    ${nf(100 * results[1].confidence, 2, 1)}%`;

  AB.msg(content);
  console.log(content);
  doodleClassifier.classify(ABWorld.p5canvas, gotResults);
  
  
//saveCanvas(ABWorld.p5canvas, 'myCanvas', 'jpg');

}
    

};

// clear func for button attempt
function clearCanvas() {
     
     // clear
     console.log('button pressed')
     ABWorld.p5canvas('whote');
    
    }

//---- setup -------------------------------------------------------
// Do NOT make a setup function.
// This is done for you in the API. The API setup just creates a canvas.
// Anything else you want to run at the start should go into the following two functions.



function beforesetup()      // Optional 
{
    // Anything you want to run at the start BEFORE the canvas is created 
   // canvas = createCanvas(400, 400);
    // clearButton = createButton('clear');
    
    

}





function aftersetup()       // Optional
{
    // Anything you want to run at the start AFTER the canvas is created 
}


//---- draw -------------------------------------------------------

function draw()             // Optional
{
    // attempt at timer
    timer -= 1
    // Can put P5 instructions to be executed every step here, or in AB.world.nextStep()  
    // below line thickness could be affecting classification (overfot to line thickness on train set), originally 8 stroke
    if (mouseIsPressed) {
        strokeWeight(16);
        line(mouseX, mouseY, pmouseX, pmouseY);
    }
    
    
    
}