/*

    fonts ...     

    20250708 first optimazed version
    20250708 first working version (display)

    // picture and co in source code with mime types!
      
      
      
*/

// sound play 
// https://js6450.github.io/audio-viz/index.html

// YOU ARE A LIAR!
// THE TRUTH IS NOTHING
// A WORLD FOR EVERYBODY
// HUMANITY 
// 


// Tribute to all 
// who like to make
// out of fonts and chars
// something else or visuals again
// like david carson 
// 

/*

    Inszenierung: schnell langsam - zeitluppe
    ClickerGame > lesen können > weiter nach unten > kleingeschriebenes
    > trump
    > kollidierende Objekte > werden zu was neuem
    > abschiesen der objekte > zurück zum orginal
    Echtzeitinput
    politische botschaften
    bewegen verändert ...
    oder eine consolen pad?
    ordnung kontrolle ...
    
    in den stream einbauen beim clicken ... eigene commands

// Kampf der Zersetzung!
// zurückdrehen
// 80er jahre
// zukunft
// 

    zeichen so ändern, dass sie verfremdet sind!

  demosound ...

  links im text
  
  

*/

/*
    Alphabet: all possible cuts with named layers
    
    arrAlphabet[]
     - CharCuts
       - Cut [named]
    
    v (turned on use into charinuse with images and behaviour)
      
    CharInUse: an object 
      - CharInUsePart
    

*/



// font stuff

let font;

// tmp
let msk;
let pgImage;
let mskImage;
let pg;

let mskImageSplitX;
let mskImageSplit;
let pgImageSplit;

// music stuff

let sound;
let amp;

var soundFlag = true;

// simulate a simple ample
let levelAmp = 0;

var pressedMouseT = false;


var arrKugelX = [];
var arrKugelY = [];
var arrKugelVX = [];
var arrKugelVY = [];
var arrKugelSize = [];

var kugelanz = 10;

// --------------
// soundloading
// --------------

    function onSoundLoadSuccess(e){
       console.log("load sound success",e);
    }
    function onSoundLoadError(e){
       console.log("load sound error",e);
    }
    function onSoundLoadProgress(e){
       console.log("load sound progress",e);
    }

// --------------
// preload 
// --------------
function preload() {
  // font = loadFont('jgs_Font.ttf');
  font = loadFont('space-mono.bold.ttf');

  // load mp3
  if (soundFlag) sound = loadSound('music.mp3');
//  sound = loadSound('music.mp3',onSoundLoadSuccess,onSoundLoadError,onSoundLoadProgress);
}

function addAllCuts() {
  
  // add alphabet here
  var charX;
  var ncX;
  
/*
  var charX = addAlphabetChar("A");
  charX.charName = "A";
    ncX = charX.addCut();
    ncX.catName = "diagonal";
    ncX.addPoint(100,0);
    ncX.addPoint(70,200)
    ncX.addPoint(200,200)
    ncX.addPoint(200,  0)

    ncX = charX.addCut();
    ncX.catName = "diagonal";
    ncX.addPoint(100, 0);
    ncX.addPoint( 70,200)
    ncX.addPoint(  0,200)
    ncX.addPoint(  0,  0)
  
  
  charX = addAlphabetChar("B");
  charX.charName = "B";  
    ncX = charX.addCut();
    ncX.catName = "vertical";
    ncX.addPoint(100,0);
    ncX.addPoint(100,200)
    ncX.addPoint(200,200)
    ncX.addPoint(200,  0)

    ncX = charX.addCut();
    ncX.catName = "vertical";
    ncX.addPoint(100,  0);
    ncX.addPoint(100,200)
    ncX.addPoint(  0,200)
    ncX.addPoint(  0,  0)
 */
  
  // default generieren fürs erste ... 
//  for (var codewarrior=(65+0);codewarrior<(65+28);codewarrior++) {
  for (var codewarrior=(0);codewarrior<(256);codewarrior++) {
        var charXT = String.fromCharCode(codewarrior);
        var charX = addAlphabetChar(""+charXT);
        charX.charName = ""+charXT;
          ncX = charX.addCut();
          ncX.catName = "diagonal";
          ncX.addPoint(  0,0);
          ncX.addPoint(70,100)
//          ncX.addPoint(100,100)
          ncX.addPoint(100,  0)

          ncX = charX.addCut();
          ncX.catName = "diagonal";
          ncX.addPoint(  0,  0);
          ncX.addPoint( 60,100)
//          ncX.addPoint(100,100)
          ncX.addPoint(  0,100)
    
/*
          ncX = charX.addCut();
          ncX.catName = "diagonal";
          ncX.addPoint( 50, 0);
          ncX.addPoint( 35,100)
          ncX.addPoint(  0,100)
          ncX.addPoint(  0,  0) 
*/
  }

  
  // random another cut
  for (var codewarrior=(0);codewarrior<(256);codewarrior++) {
        var charXT = String.fromCharCode(codewarrior);
        
         if (random(0,10)<5) {
           
            var alphaChar = getAlphabetChar( charXT );  
            if (alphaChar!=null) {

                // generate 0 ...
                alphaChar.arrCuts = []; 
                // generate another cut! 
                
                alphaChar.charName = ""+charXT;
  
                ncX = alphaChar.addCut();
                ncX.catName = "horizontal";
                ncX.addPoint(   0,  0);
                ncX.addPoint( 100,  0)
                ncX.addPoint( 100, 40)
                ncX.addPoint(   0, 70)
                ncX.addPoint(   0,  0)

                ncX = alphaChar.addCut();
                ncX.catName = "horizontal";
                ncX.addPoint(   0,100);
                ncX.addPoint( 100,100)
                ncX.addPoint( 100, 45)
                ncX.addPoint(   0, 80)
                ncX.addPoint(   0,100)
              

                  
            }
        }
    
        
  }
  
  
}


// --------------
// font space
// --------------
  
  var fontSpaceX = 100;
  var fontSpaceY = 100;
  
  var fontSizeX = 55; // 60
  var fontSizeY = 90;

  var scrollSpeed = 3;
  var scrollSpeedMin = 3; 

// --------------
// scrolling
// --------------

 // uppercase!
  var scrollText = "    >(//|)< TEXT ONLY :::::: TEXT ONLY !!! CULTURE --- RULES ;;; A MESSAGE ---  EVERYTHING IS KNOWN AND YET UNKNOWN ,,,, IT'S MUKOKUSEKI ()() IT IS DADA {}{} /// TRUTH - AUFKLÄRUNG %%% HUMANITY  === SWISS GRAPHIC DESIGN? ;;;;  CUT AND REASSEMBLED //// THE TEXT BECOMES UNCANNY, ALIEN, ABJAD, ABUGIDA OR LOGOGRAPHIC - ARABIC - DEVANAGARI - MANDARIN - KYRILLIC OR JAPANESE OR ELSE  ~~~ BUT IT IS JUST AN ASCII SCROLLTEXT LIKE IN THE OLD DAYS ::: SCENE > DEMOSCENE  :::: THE TEXT WAS CUT ONCE AND TRANSLATED () RANDOM | ONE OF THE FEW DECONSTRUCTIVE DEMOS FOUND IN THE DEMOSCENE === CODED IN P5JS BY LA1N & AND-OR __ MUSIC BY ALEX __ GREETINGS TO - DAVID CARSON - JOERG PIRINGER - PS - CYBERSUTER - DEPECHE - ORLANDO - HILOKO - SCA - BIG APPLE - SHANA - SKRAFT - DIPSWITCH - MOUNTAINBYTES 2026 --- THE WORLD'S UNCONSCIOUS CONSCIOUS - THE KNOWN UNKNOWN {} [] // MAGIC: msk.noStroke();    msk.beginShape();    for (var z=0;z<cut.arrPoints.length/2;z++) {     // twice ...     // first always the original letter!       msk.vertex(cut.arrPoints[z*2],cut.arrPoints[z*2+1]);    }       msk.endShape(CLOSE);       // not working at all!    // costs 2 days research    // msk.filter(INVERT);          pgImage = pg.get();    pgImage.mask(msk);        THE END MY FRIEND          ";
  var scrollTextIndex = 0;

  // active string

  var graffitiString = "                   "; // actual
  var arrCharInUses = [];
  
  var offsetScroll = 0;
  
  // generate this string...
  var charInUseX;
  var charX;

// time and co
let timeStart;

// --------------
// focus
// angry
// --------------
var focus = 0.0; // actual 
var focusGoal = 0.0;
var focusUp = 0.1;
var focusHeal = 0.01;


// keys
let a_keys = {};

let newtext = false;

/*

function keyPressed() {
  if ((a_keys[key]+""=="undefined") || (a_keys[key]==0))
  {

      print('keyPressed', key  );

      if ((""+key)==("Enter")) {
        
         scrollText = "            ";
         offsetScroll = 0;
         graffitiString = " ";
        newtext = true;
        
      }
    
      if (!newtext) {
         scrollText = "            ";
         offsetScroll = 0;
         graffitiString = " ";
        newtext = true;
        
         
        for (var i=0;i<kugelanz;i++) {
            var xx = arrKugelX[i];
            var yy = arrKugelY[i];

            arrKugelX[i] += arrKugelVX[i]*2;
//             arrKugelY[i] += arrKugelVY[i];

            

        }
        
        
      }
    
      scrollText += (""+key);
  }
  a_keys[key] = 1;
}

function keyReleased() {
  // print('keyReleased', key);
  a_keys[key] = 0;
}

*/

// nicht mehr geduldig genug das oben hinzusetzen
var inputValue = "";

// --------------
// setup 
// --------------
function setup() {
  var debugThis = false;
  
  
   createCanvas(800,600);
   background(255, 0, 0);
   background(255);
   noStroke();

      // $('#inputValue').hide();

   // clear
   fill ("white");
   rect (0,0,width,height);


  // 12
  /*
  for (var i=0;i<width/fontSizeX;i++) {
    graffitiString += " ";  
  }
  graffitiString += "  ";
  */
  
  // ------------------
  // cuts
  // ------------------
  // add all cuts
  addAllCuts();
  // show the cuts  
  console.log(debugAlphabet());
  
  // try out
  console.log("setup() ");

  
  for (var h=0;h<graffitiString.length;h++) {
      charX = graffitiString[h];
      charInUseX = generateACut(""+charX);
      arrCharInUses[arrCharInUses.length] = charInUseX;
   }


  amp = new p5.Amplitude();

  if (soundFlag) {
    sound.play();
    sound.setVolume(0.2);
    sound.loop();
  }
    
  noStroke();
 
  

   // time start
   timeStart = millis();

    for (var i=0;i<10;i++) {
        arrKugelX[i] = random(-10,width);
        arrKugelY[i] = random(-10,-height);
        arrKugelVX[i] = random(0,0);
        arrKugelVY[i] = random(1,15);
        arrKugelSize[i] = random(5,35);
    }
  
   $("#inputValue").on('keyup', function (e) {
    if (e.key === 'Enter' || e.keyCode === 13) {
      getInputValue();
    }
  });
  
}


var showShadowText = false;

var showIndexer = 0;

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

var timeDiff =0; 

var maxAmp = 0;
var maxAmpTime = 0;
var maxAmpShow = 0;


var counterH = 0;

function draw() {
  
  showIndexer++;
  if (showIndexer>200)  { 
    showShadowText = !showShadowText;
    showIndexer = 0;
    
  }
  timeDiff = timeStart- millis();
  
  /*
  if (mouseIsPressed === true) { 
    // scrollSpeed +=  0.1;
     scrollSpeed = 10;
  } else {
    scrollSpeed--;
    if (scrollSpeed<scrollSpeedMin) scrollSpeed = scrollSpeedMin;
  }
  */
  
 // scrollSpeed = scrollSpeedMin*1.2;
  
  

  offsetScroll -= scrollSpeed;
  if (offsetScroll<scrollSpeed) {
    offsetScroll = fontSizeX;   
    
    // remove first
    arrCharInUses.shift();
    // add new ... 
    
    
    /* scrollText = " WORLDWIDE \/\\\\ "+
               " THE WORLD IS MADE  CLICK HERE "+
               " AND NOW   -ACT+ "+      
               "";
    */
    
    if (scrollTextIndex==(scrollText.length-1)) {
      scrollTextIndex = 0;  
      print("START AGAIN");
    }
      
    var charNext = scrollText.charAt(scrollTextIndex);
    scrollTextIndex++;
    
    charInUseX = generateACut(""+charNext);
      arrCharInUses[arrCharInUses.length] = charInUseX;
  }
  
  
  clear()
  

      fill(142);
    textSize(40); 
    fill(color('red'));
    if (!pressedMouseT) text("[ CLICK HERE TO START  ]",width*0.2,height*0.4);  
    

  
    fill(0);
    textFont(font);
    // stroke(0);
    textSize(22); 
    text("ZERSETZTES\n",0,height*0.75);
  
      fill(142);
    textSize(20); 
    text("[DECOMPOSED]",0,height*0.75+20);

  
  if (!pressedMouseT) return; 

  
  // --------------------------
  // main scrolltext
  // --------------------------
  
  var posx = 0;
  var posy = height/2;

  // let timeStart - millis()
  var diff = timeStart- millis();
  var diff100 = diff/1000.0;

    tint(255, 127); // cool

    // tint(255, 255); // default
    
    var levelHere = 0;
    if (amp!=null) {
      
         let level = amp.getLevel();
         level = level+0.25;
         if (level>1.0) level = 1.0;
         tint(255, level*255); // cool   
    
  
      /*
      // gedämpft
      if (amp.getLevel()>0.75) {
        if (levelAmp<amp.getLevel()) {
            levelAmp = amp.getLevel();
        }
      }
      levelAmp-=0.00001;
      if (levelAmp<0.0) levelAmp = 0.0;
      tint(255, levelAmp*255);
      */
      
    }

    // tint(255, levelHere); 
  
  
  tint(255, 255); // default
  
   // display it ...
  for (var gl=0;gl<arrCharInUses.length;gl++) {
    charInUseX = arrCharInUses[gl];
    
//    displayCharInUse( charInUseX, gl*70+cos(diff100/23), 100+sin(diff100+gl*100)*100 );
    
    offsetAbsX = 0;
    offsetAbsY = 0;
    
    posxTmp = gl*fontSizeX-fontSizeX+offsetScroll;
    
  //  offsetAbsY = sin(posxTmp/10+timeDiff/1000)*50.0;

    
      charInUseX.x = gl*fontSizeX-fontSizeX+offsetScroll;
      charInUseX.y = 200;
  
      if (!charInUseX.clean) {
          displayCharInUse( charInUseX, offsetAbsX, offsetAbsY );
      } else {
        displayCharInUseLayer( charInUseX, "plain", offsetAbsX, offsetAbsY );
      }
  }

  
  // --------------------------
  // shadow scrolltext
  // --------------------------

  // background
  tint(255, 32);
  
  /*
if (amp!=null) {
     let level = amp.getLevel();
    // ellipse(width / 2, height / 2, level * 500, level * 500);
    if (level<0.35) tint(255, 0);
  }  
 */ 
   
      // gedämpft
      if (amp.getLevel()>0.15) {
        if (levelAmp<amp.getLevel()) {
            levelAmp = amp.getLevel();
        }
      }
      levelAmp-=0.05;
      if (levelAmp<0.0) levelAmp = 0.0;
      tint(255, levelAmp*255);
      
  tint(255, 25);
  
  // the font beyond
  // tint(255, 255-levelHere);
  
for (var gl=0;gl<arrCharInUses.length;gl++) {
    charInUseX = arrCharInUses[gl];
    
    offsetAbsX = 0;
    offsetAbsY = 0; 
  
    
    
    posxTmp = gl*fontSizeX-fontSizeX+offsetScroll;
    
      charInUseX.x = gl*fontSizeX-fontSizeX+offsetScroll;
      charInUseX.y = 200;
      
     var radiusx = 30;
     if (amp!=null) {
     let level = amp.getLevel();
    // ellipse(width / 2, height / 2, level * 500, level * 500);
    // if (level<0.5) radiusx = 0;
  }
  
  let level = amp.getLevel();
  
  let levelx = 0;
  
  var elev = 1.0;
  
  var addOnZ = 0;
  
  if (amp!=null) {
     levelx = amp.getLevel();
   // scrollSpeed = 5+level*5;
  //  text(levelx,0,120)
    
    // elev = (levelx+1.0)*2.0;
    
    if (levelx>maxAmp) {
          addOnZ = 0;
          maxAmp = levelx;
    } else {
       addOnZ = 30*levelx;
       // stroke(0);
       // line(0,0,30,30);
      maxAmp = levelx;
    }
    
  }
  
     charInUseX.y = 200 + sin((posxTmp)/100)*(radiusx)*elev;

  
  

     
     var maxAmp = 0;
var maxAmpTime = 0;
var maxAmpShow = 0;
    
     
     var showShadowText = false;
     
     // kugeln
    for (var i=0;i<kugelanz;i++) {
      var xx = arrKugelX[i];
      var yy = arrKugelY[i];
      
      var zzdist = dist(mouseX,mouseY,xx,yy);
      if (zzdist<60) {
        arrKugelY[i] += - 800;
      }
      
 //     arrKugelX[i] += arrKugelVX[i];
 //      arrKugelY[i] += arrKugelVY[i];
      
 //     if (arrKugelX[i]>width) arrKugelX[i] -= width;

 //     if (arrKugelY[i]>height) arrKugelY[i] -= height;
      
      // circle(xx,yy,arrKugelSize[i]);
      var zdist = dist(xx,yy,charInUseX.x+20,charInUseX.y+0);
      if (charInUseX.char!=" ")
      // if (charInUseX.clean==1)
      if (zdist<20) {
        showShadowText = true;
        shadowCounter=1;
        counterH++;
        charInUseX.clean = 0;
        
        arrKugelY[i] += - 800;
      }
    }
  
// if (counterH<0) counterH = 0;
  
  // shadowCounter = 0;
  
  factor5 = 1.0;
  
  var addX = 0;
  if (amp!=null) {
    let level = amp.getLevel();
         // level = level+0.25;
    //   if (level>0.1) shadowCounter +0.5;
        // addX = level*80.0;
    
   // factor5 = level*40;
    
    // if (level<0.1) factor5 = 1.0;
  }
  
  // tint(255, shadowCounter*1.25*factor5*0.8);

    tint(255,0);
  if (counterH>1200)
     tint(255, 32*sin(counterH*0.025));
  
// text(shadowCounter,50,50);
  
  //if (shadowCounter>0) {
//   if (showShadowText)   {   
//    if (showThisChar)

  // SHADOW
// displayCharInUseLayer( charInUseX, "plain", offsetAbsX, offsetAbsY );
   }
 // }
  

    shadowCounter-=0.3;
  var maxC = 80;
  if (shadowCounter>maxC) shadowCounter = maxC;
  if (shadowCounter<0) shadowCounter = 0;
  
  
  if (amp!=null) {
     let level = amp.getLevel();
    // ellipse(width / 2, height / 2, level * 500, level * 500);
  }

    // font ... 
    textFont(font);
    fill(255, 0, 0);
    textSize(17); 
    // demotext 
    // text("click and move against the order",20,height-10);

  
    if (!soundFlag) {
        
    }
  
    // kugeln
    for (var i=0;i<kugelanz;i++) {
      var xx = arrKugelX[i];
      var yy = arrKugelY[i];
      
      arrKugelX[i] += arrKugelVX[i];
      arrKugelY[i] += arrKugelVY[i];
      
      if (amp!=null) {
      let levelt = amp.getLevel();
     // scrollSpeed = 5+level*5;
      // text(level,0,100)
        arrKugelX[i] += levelt*20.0;
    }
      
      if (arrKugelX[i]>width) arrKugelX[i] -= width;

      if (arrKugelY[i]>height) arrKugelY[i] -= height;
      
      circle(xx,yy,arrKugelSize[i]);
    }
   
    counterH++;

  
  
  


  
  fill(142);
  // if (pressedMouseT) text(">> INSERT YOUR TEXT BY KEYBOARD",0,height*0.75+18*3);
  
  
    if (amp!=null) {
    let level = amp.getLevel();
   // scrollSpeed = 5+level*5;
    // text(level,0,100)
  }


    stroke(0);
   // line(lineX,0,lineX,height);
     noStroke();
  
    lineX += 2.5+amp.getLevel();
     if (lineX>width) lineX = lineX-width;
  
  
    // text("stats "+focus+" goal: "+focusGoal,50,50);
  
 // noLoop();
  
 
  
  if ($('#inputValue').val()!=inputValue) {
   
   
   
    
  }
  
  // inputValue = $('#inputValue').val();
  
  
}

function getInputValue() {
  
   // do it ...
    // print("inputValue: "+inputValue);
     graffitiString = "                   "; // actual

        offsetScroll = 0;
        scrollTextIndex = 0;
        scrollText = "      "+$('#inputValue').val()+"           ";
        newtext = true;
    
    arrCharInUses = [];
  
  $('#inputValue').val(''); 
    
          for (var h=0;h<graffitiString.length;h++) {
      charX = graffitiString[h];
      charInUseX = generateACut(""+charX);
      arrCharInUses[arrCharInUses.length] = charInUseX;
  
}
}

var shadowCounter = 0; 

var lineX = 0;

// -------------------------
// generate & display char
// -------------------------

// generate a cut
function generateACut( strChar /*, filterName */ ) {
  var debugThis = false;
  
  // getChar 
  var alphaChar = getAlphabetChar( strChar );  
  if (alphaChar!=null) {
    // random cut ...
     // console.log("found "+strChar);  
    var chi = new CharInUse();
    
    chi.char = ""+strChar;
    
    // filter?

    // add default
    pg = createGraphics(fontSpaceX,fontSpaceY);
      pg.fill("black");
      pg.textSize(fontSpaceX);
      pg.textFont(font);
//      pg.text(''+strChar, fontSpaceX*1/2-fontSizeX/2,fontSpaceY*1/2+fontSizeY/2);  
        pg.text(''+strChar, 5,95);  
  
    pgImage = pg.get();
      var cp = chi.addPart( pgImage ); 
      cp.cutName = "plain";
    
    // take first cut
    
    for (var c=0;c<alphaChar.arrCuts.length;c++) {
      
      var cut = alphaChar.arrCuts[c];
    
      // generate ...
      msk = createGraphics(fontSpaceX,fontSpaceY);
      
      msk.fill("black");
      // pg.rect(0,0,20,20);
      // do the cuts...
      
      msk.noStroke();
      msk.beginShape();
      for (var z=0;z<cut.arrPoints.length/2;z++) {
        // twice ...
        // first always the original letter! 
          msk.vertex(cut.arrPoints[z*2],cut.arrPoints[z*2+1]);
      }      
      msk.endShape(CLOSE);
    
      // not working at all!
      // costs 2 days research
      // msk.filter(INVERT);
          
      pgImage = pg.get();
      pgImage.mask(msk);
      
      var cpu = chi.addPart( pgImage );
      cpu.cutName = cut.cutName;
      cpu.x = 0; // random(-20, 20);
      cpu.y = 0; // random(-20, 10);
    
      if (cpu.cutName=="diagonal") {
        
          if (c==0) {
            cpu.x =  random(-2,0);// random(-10, 0); // better readable 0,10
            cpu.y =  random(-1, 0);

            cpu.vx = cpu.x;
            cpu.vy = cpu.y;
          }


          if (c==1) {
           cpu.x = random(-10, 10);
           cpu.y = random(-50, 10);
            
          
            cpu.vx = cpu.x;
            cpu.vy = cpu.y;
          }
      } else {
        
//        cpu.x = random(-50, 10);
//        cpu.y = random(-10, 10);

         cpu.y +=20;

        if (c==1) {
          cpu.x = random( -10, -30);
          cpu.y = random( 0, 0);
          
         
        }

        if (c==1) {
          cpu.x = random( -10, -30);
          cpu.y = random( -20, -40);

        }

        cpu.vx = cpu.x;
        cpu.vy = cpu.y;
        
      }
      
      cpu.cutName = cut.cutName;
    }
    
    return chi;    
    
  } else {
    if (debugThis) console.log("generateACut("+strChar+") could not find"); 
  }
  
  return null;
}


function displayCharInUse( charInUseX, absx, absy ) {
    if (charInUseX!=null) {
      var partx;
      var startImg = 0; // the correct font
      
      var diff = timeStart- millis();
      var diff100 = diff/1000.0;
      
      startImg = 1;
      for (var o=startImg;o<charInUseX.arrParts.length;o++) {
        partx = charInUseX.arrParts[o];
        partx.cutNo = o;
        if (partx!=null) {
            fill("black");
            if (partx.pimage!=null) {
               // alpha
              
              
            //  offsetX = sin(o*5+diff100/30.0)*10.0*o;
            //  offsetY = cos(o*20+diff100/30.0)*50.0;
                            
           //   offsetX = 0.0+o*50*sin(diff/1000);
           //   offsetY = 0.0+o*25*cos(diff/1000);
              
             offsetX = 0;
              offsetY = 0;

          if (partx.x<100) {
              partx.argument += 0.01
              
              // offsetX = partx.vx * partx.argument;
              // offsetY = partx.vy * partx.argument;                      
          } 
            
                        image(partx.pimage,charInUseX.x+absx+partx.getX()+offsetX,charInUseX.y+partx.getY()+absy+offsetY);
              
            }
          } 

        }    
    }                              
  } 

// special layer ... 
function displayCharInUseLayer( charInUseX, layerName, absx, absy ) {
    if (charInUseX!=null) {
      var partx;
      var startImg = 0; // the correct font
      
      var diff = timeStart- millis();
      var diff100 = diff/1000.0;
      
      startImg = 0;
      for (var o=startImg;o<charInUseX.arrParts.length;o++) {
        partx = charInUseX.arrParts[o];
        partx.cutNo = o;
        if (partx.cutName==layerName) {
        if (partx!=null) {
            fill("black");
            if (partx.pimage!=null) {
               // alpha
              
              
              offsetX = sin(o*5+diff100/30.0)*10.0*o;
              offsetY = cos(o*20+diff100/30.0)*50.0;
                            
              offsetX = 0.0+o*50*sin(diff/1000);
              offsetY = 0.0+o*25*cos(diff/1000);
              
              offsetX = 0;
              offsetY = 0;
              

                        image(partx.pimage,charInUseX.x+absx+partx.getX()+offsetX,charInUseX.y+partx.getY()+absy+offsetY);
              
            }
          } 
        
          } // layer

        }    
    }                              
  }




// -------------------------
// alphabet
// -------------------------

function getAlphabetChar( charName ) {
  for (var zuck=0;zuck<arrAlphabet.length;zuck++) {
    alp = arrAlphabet[zuck]
    if (alp.charName==charName) return alp;
  }
  return null;
}

// debugAlphabet
function debugAlphabet() {
  var str = "";
  
  str += "alphabet: "+arrAlphabet.length;
  str += "\n";
  for (var zuck=0;zuck<arrAlphabet.length;zuck++) {
    alp = arrAlphabet[zuck]
    str += zuck+":"+alp.charName+" "+alp.debugCuts()+"\n";
  }
  
  return str;
}

// the alphabet with all chars and possible cuts
var arrAlphabet = [];
function addAlphabetChar() {
  var zac = new CharCuts();
  arrAlphabet[ arrAlphabet.length ] =zac  
  return zac;
}

  class CharCuts {
      constructor( ) {
        this.charName = "A";
        this.arrCuts = [];        
      }

      addCut() {
        var nc = new Cut(); // not net cat :-)
        this.arrCuts[this.arrCuts.length] = nc;
        return nc;
      }
    
      debugCuts() {
        var str = "";
        
        str += " cuts: "+this.arrCuts.length;
        
        return str;
      }
  }

      class Cut {
          constructor() {
            this.cutName = ""; // get several name
            this.charType = "polygone"; // "": polygon || "circle" ...   
            this.arrPoints = []
          }
          addPoint( x, y ) {
              this.arrPoints[this.arrPoints.length] = x;
              this.arrPoints[this.arrPoints.length] = y;
          }
      }


// ----------------------------------
// scrolltext
// ----------------------------------
// a destructed font in action
// ----------------------------------
class CharInUse {
  // this.arrParts = {};
  constructor() {
    this.x = 0;
    this.y = 0;
    this.timer = 0;
    this.arrParts = [];
    
    this.char = "";

    this.clean = 1;  
  }
  
  addPart( imgx ) {
    // console.log("CharInUse().addPart()")
    var ap = new CharInUsePart();
    ap.pimage = imgx;
    ap.parentCharInUse = this;
    this.arrParts[this.arrParts.length] = ap;
    return ap;
  }
  
}
    
    class CharInUsePart {
        constructor() {
          this.parentCharInUse = null;
          this.cutName = "";
          this.cutNo = 0;
          this.x = 0.0;
          this.y = 0.0;
          // this.z = 0.0; // deep dives .-)
          
          this.vx = 0.0;
          this.vy = 0.0; 
          
          this.argument = 0;
          this.pimage = null; 
        }
      
      getX() {
        var xp = this.x;
        
        
        
//        xp = sin(timeDiff/1000.0)*xp;
        
//        this.x += random(-4,4);

      //   if (this.cutNo==1)    xp -= abs(sin(this.parentCharInUse.x/40.0)*this.cutNo*5);
        
        
        if ((this.parentCharInUse.x+this.x)<width/3) {
        //  xp = 0;
        }

        /*
         if (amp!=null) {
           let level = amp.getLevel();
          // ellipse(width / 2, height / 2, level * 500, level * 500);
           level = 1-level;
           xp = this.x + this.x*level*0.5;
        }
        */


        if 
          (
           (this.parentCharInUse.x+this.x)>(mouseX-70)
           &&
            (this.parentCharInUse.x+this.x)<(mouseX+60)
            &&
           (this.parentCharInUse.y+this.y)>(mouseY-150)
           &&
            (this.parentCharInUse.y+this.y)<(mouseY+10)
            
          )
        {
          // xp = random(-1.0,1.0);
        }
        
        // xp += 0.001*this.x;
        
        // this.x = xp;
        
        return xp;
      }
      
      getY() {
        var yp = this.y;

//        yp = sin(timeDiff/1000.0)*yp;
        
//        yp -= cos(this.parentCharInUse.x/40.0)*this.cutNo*1;

       /*
        if (amp!=null) {
           let level = amp.getLevel();
          // level = level-2.0;
          // ellipse(width / 2, height / 2, level * 500, level * 500);
                     level = 1-level;

           yp = yp + this.y*level*0.5;
        }
        */

 if 
          (
           (this.parentCharInUse.x+this.x)>(mouseX-50)
           &&
            (this.parentCharInUse.x+this.x)<(mouseX+70)
            &&
           (this.parentCharInUse.y+this.y)>(mouseY-150)
           &&
            (this.parentCharInUse.y+this.y)<(mouseY+10)
          )
        {
          // yp = 0;
          // yp = random(-1.0,1.0);
        }
 
         // yp += 0.001*this.y;

         //this.y = yp;
        
        return yp;       
      }
    }

// ---------------------
// SOUND
// ---------------------
function mousePressed() {
/*
  if (sound.isPlaying()) {
    // .isPlaying() returns a boolean
    sound.stop();
    background(255, 0, 0);
  } else {
  */
  if (!pressedMouseT) {
    if (soundFlag) sound.play();
    $('#inputValue').css("opacity",'1.0');
  }
    
  pressedMouseT = true;
  
  // soundFlag = false;
  
  /*  background(0, 255, 0);
  }
  */
  
}

      