/* autogenerated by Processing revision 1293 on 2024-11-11 */
import processing.core.*;
import processing.data.*;
import processing.event.*;
import processing.opengl.*;

import java.util.HashMap;
import java.util.ArrayList;
import java.io.File;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;

public class sketch_AmigaBOB1616Editor extends PApplet {

/*
      ### AMIGABOBEditor (BLITTEROBJECTS) ###
      16x16 Bobeditor for Assembler 
      
      Code by René Bauer (rene.bauer@zhdk.ch) @ chludens (Experimental archeology)

      Based on a similiar C64 Blockeditor (Therfore a lot of c64 related stuff, sorry)
      
*/

float version = 0.77f;

boolean importC64DataActive = false;

boolean addByte = true;

// export no blocks to asm l
// blocksASMAmount
int blocksASMAmount = 98;

// how many bitplanes 2^bitplanes 
int bitplanes = 4; // colors
int amountColors = 32; // 2^bitplanes 

// values per red or green or blue
int bitsPerColor = 4; // atari st = 3 - 512 | amiga 4 or 5 - 16/32 


// tools
String[] arrTools = { "d", "f", "nl", "c","r","cp","pa", "nl",    "flx","fly","ml","mu"};
String[] arrToolsName = { "draw", "fill", "nl", "clear","rnd","copy","paste", "nl",    "<>","^v", "|<","^_" /*">v"  ,"<","v" */ };
int[] arrToolType={1,1,0,0,0,0,0,0,0,0,0,0,0,0};

String toolSelected = "d";

// levels
int[] arrLevels = { 43, 44,45, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19, 20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, 42 };

// the playfield
int[] arrPlayfield = new int[320]; // 16*20

int[] arrCopyPastePlayfield = new int[320];


Block[] arrBlocks = new Block[256];
int selectedBlock = 1;

Block copypasteBlock = new Block();

int selectedSegment = 0;

int paintColor = 1;

int backgroundColor = 0;
int borderColor = 0;
  
  int ibackgroundColor = 0;
  int iborderColor = 0;

int[][] arrColorfield = 
      {
        { 0,11,12,15, 1},
        {-1,-1, 6,14, 3},
        {-1,-1, 5,13, 7},
        {-1,-1, 4,10, 8},
        {-1,-1,-1,2, 9},
        {-1,-1,-1, 4, -1}
      };

int editorMode = 1;

int startXFocus = 3;
int startYFocus = 2;
 
 // offset right 
int offsetRightY = 25;

String msg = "Started up";

class Block {
   
   public int index = -1;
  
   public Segment[] arrSegments = new Segment[1];
   
   public void clear() {
       arrSegments[0].initColors();
   }
   
   public void changeColor( int fromCol, int toCol ) {
       arrSegments[0].changeColorSegment(fromCol,toCol);
   }
   
   public void randIt() {
       arrSegments[0].reset();
   }
   
   public void updateFrom( Block updateFrom ) {
       arrSegments[0].updateFrom(updateFrom.arrSegments[0]);
   
   }
  
   public C64Color getBlockColor( int x, int y ) {

     // println("getBlockColor() "+segmentindex+" ("+x+","+y+") "+rx+" "+ry+" ("+(rx+ry*4)+")"+"   "+arrSegments[segmentindex].arrColors.length);
     return arrSegments[0].arrColors[x+y*16];
   }
 
   public int getBlockPixel( int x, int y ) {
     C64Color cox = getBlockColor(x,y);
     return cox.c64Color;
   }
   
   public void setBlockPixel( int x, int y, int val ) {
     C64Color cox = getBlockColor(x,y);
     cox.c64Color = val;
   }
   
   
}

    class Segment {
       
       int colorDraw = 0;
       int colorMulti1 = 0;
       int colorMulti2 = 0;
       
       // all colors ...
       int[] arrColor = new int[16*16];
       
       int colorCounter = 0;
       
       boolean colorsAreTrue = true;
   
       
       // 4*8 pixsel
       // pixel in real afterwards take down?
       
       public C64Color[] arrColors = new C64Color[16*16];
       
       
       // compressed
       public int[] arrCompressedColors = { 0,0,0,0,0,0,0,0 };
       
       public void initColors() {
         for (int p=0;p<256;p++) {
            C64Color c64col = new C64Color();
            c64col.c64Color = backgroundColor;
            arrColors[p]  = c64col;
         }
       }
       
       public void reset() {
          
        for (int p=0;p<256;p++) {
          arrColors[p]  = new C64Color();
          float rndx =  random(16);
          arrColors[p].c64Color = PApplet.parseInt(rndx); // int( rndx );
        }
         
       }
       
       public void updateFrom( Segment xyz ) {
         
         for (int p=0;p<256;p++) {
          arrColors[p].updateColors( xyz.arrColors[p] );
          
        }
        
        updateSudokuColors();
        
       }
       
       public void setPixel(int x, int y, int val) {
         if (x<0) return ;
         if (x>16) return ;
         if (y<0) return ;
         if (y>16) return ;
         
         arrColors[x+y*16].c64Color = val;
       }
       
       public int getPixel(int x, int y) {
           if (x<0) return -1;
           if (x>16) return -1;
           if (y<0) return -1;
           if (y>16) return -1;
           return arrColors[x+y*16].c64Color;
       }
       
       public void changeColorSegment( int fromCol, int toCol ) {
         
         for (int p=0;p<64;p++) {
          C64Color con = arrColors[p];
          if (con.c64Color==fromCol) con.c64Color = toCol;
        }
       }
       
       
       public void updateSudokuColors() {
         
         
         
         /*
         colorsAreTrue = true;
         
         int[] arrColUsed = {0,0,0,0,0,0,0,0,0,0,0,0,0,0};
         
         
         int found = 0;
         
         // go through the colors
         int statec = 0;
         
         colorDraw = backgroundColor;
         colorMulti1 = backgroundColor;
         colorMulti2 = backgroundColor;
         
         for (int p=0;p<32;p++) {
            C64Color c64colx = arrColors[p];
            // check   
            if (c64colx.c64Color!=backgroundColor) {
              // it is a color
              boolean foundx = false;
              for (int r=0;r<arrColUsed.length;r++) {
                int usex = arrColUsed[r];
                if (usex==c64colx.c64Color) {
                  foundx = true;
                  break;
                }
              }
              if (!foundx) {
                 arrColUsed[statec] = c64colx.c64Color;
                 if (statec==0) colorDraw = c64colx.c64Color;
                 if (statec==1) colorMulti1 = c64colx.c64Color;
                 if (statec==2) colorMulti2 = c64colx.c64Color;
                 statec++; 
              }
              
            }
            // arrColUsed
         }
         
         // code now .. 
         
         // p ... 
         for (int p=0;p<8;p++) {
            int c64colx0 = encode4Bit(arrColors[p*4+0].c64Color);
            int c64colx1 = encode4Bit(arrColors[p*4+1].c64Color);
            int c64colx2 = encode4Bit(arrColors[p*4+2].c64Color);
            int c64colx3 = encode4Bit(arrColors[p*4+3].c64Color);
            // 8 bit
            int val0 = c64colx0<<6; //c64colx0<<0;
            int val1 = c64colx1<<4; //c64colx1<<1;
            int val2 = c64colx2<<2; //c64colx2<<2;
            int val3 = c64colx3; // c64colx3<<3;
            
            // value ...
            
            arrCompressedColors[p] = val0 | val1 | val2 | val3;
            
           // arrCompressedColors[p] = val0;
         }
         
         colorCounter = statec;
         
         if (statec>3) {
             colorsAreTrue = false;
         }
         */
       }
       
       public int encode4Bit(int colx) {
         
         if (colx==backgroundColor) return 0;
         if (colx==colorDraw) return 3; // 01
         if (colx==colorMulti1) return 1; // 10
         if (colx==colorMulti2) return 2;  // 11
         
         return 0;
       }
       
       public String getColorNumbers() {
         
         updateSudokuColors();
         
         String str = "";
         
         str += colorDraw+","+colorMulti1+","+colorMulti2 +",      ";
         
          for (int u=0;u<16;u++) {
             str += arrCompressedColors[u];
             if (u!=7) str += ","; 
          }
          
          if (!colorsAreTrue)
          str += ">3 colors!";
         
         return str;
       }
       
       public String getColorNumbersAsm() {

       
        String[] arrB = new String[bitplanes];

        for (int i=0;i<bitplanes;i++) {
             arrB[i]="\n\t\tdc.b %";
        }


        // 255 
        for (int z=0;z<256;z++) {
//         if (true) {

             int col = arrColors[z].c64Color;
             
             // arrColors[zz*16+z].c64Color
             
             // col=12;
              
            if (z>0 && z%8==0 && z%16!=0) {
              for (int i=0;i<bitplanes;i++) {
                 arrB[i] += ",%"; 
              }
            }
            
            if (z>0 && z%16==0) {
              for (int i=0;i<bitplanes;i++) {
                if (addByte) arrB[i] += ",0,0"; 
                arrB[i] += "\n\t\tdc.b %"; 
              }
            }
             

           // if (col!=0) println(" "+col);
           
           for (int i=0;i<bitplanes;i++) {
               // arrB[z]=            
               // if (testBit(i)) {
               // arrB[i] += " - ";
               if ((col & (1L << i)) != 0) {
                 arrB[i] += "1";
               } else {
                 arrB[i] += "0";               
               }
               
           }
           
         }

           for (int i=0;i<bitplanes;i++) {
              println(i+"  "+arrB[i]); 
           }

         
         String allinone = "";
         
         for (int i=0;i<bitplanes;i++) {
            allinone += "\n\t\t; plane_"+i+arrB[i]+"";
            
            if (addByte) allinone+=",0,0"; // add 2 bytes
         }
         
         // add the mask ...
         
         
         print(allinone);
         
         return allinone+"\n";
         
         /*
         updateSudokuColors();
         
         String str = "";
         
          for (int u=0;u<8;u++) {
             str += arrCompressedColors[u];
             str += ","; 
          }
          
          int multimerge = colorMulti2;
            int multimerg2shifted = colorMulti1<<4;
           multimerge = multimerge | multimerg2shifted;  
          str += "  "+colorDraw+","+multimerge+"/--/,"+0 +" \n ";
        
         return str;
         */
       }
    }

      class C64Color {
         
      int c64Color = 0;     // 0-15
      int c64RealColor = 0; // effective
            
      public void setFillColor() {
        fill(c64Color);
       //  print(c64Color+"  ");
      }
      
      public void updateColors( C64Color copy ) {
          c64Color = copy.c64Color;
          c64RealColor = copy.c64RealColor;
          
      }
   }

  
class Color {
   
  // 0-255
  int r = 0;
  int g = 0;
  int b = 0;

  // 0-8 atari st | 0-16 amiga 
  int systemR = 0;
  int systemG = 0;
  int systemB = 0;
  
  public Color( int rr, int gg, int bb ) {
     
    systemR = rr;
    systemG = gg;
    systemB = bb;
    
    updateGlobalColors();
        
  }
  
  
  public void init( int rr, int gg, int bb ) {
    systemR = rr;
    systemG = gg;
    systemB = bb;
    
    updateGlobalColors();
  }
  
  // create 0-255 colors (true color)
  public void updateGlobalColors() {
    
    int max = 16; // 4096 colors
    int trueMax = 256;
    
    int factor5 = trueMax / max;
    
    // 256
    r = systemR *factor5;
    b = systemB *factor5;
    g = systemG *factor5;
    
  }

  
}




Color[] arrCol = {  };

int[] c64Colors = { 0, 1, 2, 3, 4, 5, 6, 7, 8,9, 10,11, 12,13,14,15, 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 };
Color[] c64ColorRGB = new Color[32];


// string[] 64ColorsName = { "black", "white"};

public void setup() {
   
  /* size commented out by preprocessor */;
  
  // init
  for (int z=0;z<256;z++) {
     Block blockO = new Block();
     arrBlocks[z]=blockO;
     initBlock(blockO);
     
  }
  
  // copybase
  initBlock(copypasteBlock);

  // playfields
  for (int o=0;o<320;o++) {
     arrPlayfield[o] = 0; // int(random(256));
  }
 
  // colors
  
      // 
      // 16*16*16 = 4096 - 12 bit
      // vs 256*256*256
      //
      
      c64ColorRGB[0] = new Color(0,0,0);
     
      c64ColorRGB[1] = new Color(4,4,4);
      c64ColorRGB[2] = new Color(8,8,8);
      c64ColorRGB[3] = new Color(12,12,12);      
      c64ColorRGB[4] = new Color(16,16,16); // new Color(204,68,204);
      
      c64ColorRGB[5] = new Color(4,0,0);
      c64ColorRGB[6] = new Color(8,0,0);
      c64ColorRGB[7]  = new Color(12,0,0);
      c64ColorRGB[8]  = new Color(16,0,0);
      
      c64ColorRGB[9]  = new Color(0,4,0);
      c64ColorRGB[10] = new Color(0,8,0);
      c64ColorRGB[11] = new Color(0,12,0);
      
      c64ColorRGB[12]  = new Color(0,0,4);
      c64ColorRGB[13]  = new Color(0,0,8);
      c64ColorRGB[14]  = new Color(0,0,12);
      c64ColorRGB[15]  = new Color(12,0,12);

      c64ColorRGB[16]  = new Color(90,90,90);
      c64ColorRGB[17]  = new Color(90,90,90);
      c64ColorRGB[18]  = new Color(90,90,90);
      c64ColorRGB[19]  = new Color(90,90,90);
      c64ColorRGB[20]  = new Color(90,90,90);
      c64ColorRGB[21]  = new Color(90,90,90);
      c64ColorRGB[22]  = new Color(90,90,90);
      c64ColorRGB[23]  = new Color(90,90,90);
      c64ColorRGB[24]  = new Color(90,90,90);
      c64ColorRGB[25]  = new Color(90,90,90);
      c64ColorRGB[26]  = new Color(90,90,90);
      c64ColorRGB[27]  = new Color(90,90,90);
      c64ColorRGB[28]  = new Color(90,90,90);
      c64ColorRGB[29]  = new Color(90,90,90);
      c64ColorRGB[30]  = new Color(90,90,90);
      c64ColorRGB[31]  = new Color(90,90,90);

      loadBlocks();
      loadPlayfield();
}

  public void initBlock( Block blockInstance ) {
     
       blockInstance.arrSegments[0] = new Segment();
       blockInstance.arrSegments[0].initColors();
     
  }

int posX = 0;
int posY = 50;

  public Color getColor( int index ) {
    
    if (index==42) index = 3;
    
    return c64ColorRGB[index];
  }

boolean mousePressedHistory = false;

public void draw() {
  
  // title
  Color dcox = getColor(backgroundColor);
  fill(dcox.r, dcox.g, dcox.b);
  
  background(dcox.r, dcox.g, dcox.b);
  
  Color cox = getColor(backgroundColor);
  fill(cox.r, cox.g, cox.b);

  fill(0,0,0);
  rect(0,0,500,50);

  fill(255);
   
  // title
  textSize(40);
  text("CBA CAMIGA_BOB_EDITOR "+version+" (BLITTEROBJECTS)",0,40);
  
  fill(0);
  rect(10,65,700,20);
  fill(255);
  textSize(16);
  text("BOB_EDITOR (COLOR 0: TRANS)                         BOBS                                                                            ",10,80);
  
    // load and save blocks
    String[] arrToolsBlocks = { "load","save"};
    int bsx = 450;
    int bsy = 62;

    for (int z=0;z<arrToolsBlocks.length;z++) {
       String namexyz = arrToolsBlocks[z];
      
      fill(80,80,80);
      rect(bsx,bsy,50,20);
      
      fill(255);
      text(namexyz,bsx,bsy+20);
      
      if (mousePressedHistory==false) {
       if (mousePressed) {
         if ((mouseX>bsx)&&(mouseX<(bsx+40))) {
         
           if ((mouseY>bsy)&&(mouseY<(bsy+20))) {
             
             if (namexyz.equals("load")) {
               loadBlocks();
             }
             
             if (namexyz.equals("save")) {
               saveBlocks();
             }
             
             
           }
         }
       }
     } 
     
     bsx += 60;
     
    }
    
   if (false) {
  
    // levels
    int levx = 620;
    int levy = 100;
    int btnSize = 25;
   
    // move down
      fill(80,80,80);
      rect(levx,levy,btnSize-4,20);

     fill(240,240,240);
      text("^",levx+4,levy+10);
      
      if (mousePressedHistory==false) {
       if (mousePressed) {
         if ((mouseX>levx)&&(mouseX<(levx+btnSize))) {
                 
           if ((mouseY>levy)&&(mouseY<(levy+20))) {
             
               int[] af = new int[20];
               for (int ii=0;ii<20;++ii) {
                  af[ii]=arrPlayfield[ii];
               }
               for (int i=1;i<16;++i) {
                  for (int ii=0;ii<20;++ii) {
                    int fi = arrPlayfield[i*20+ii];
                    arrPlayfield[(i-1)*20+ii]=fi;                   
                 }
               }
               for (int ii=0;ii<20;++ii) {
                  arrPlayfield[15*20+ii]=af[ii];
               }
               
             
           }
         }
       }
      }
    
    // 0-40
    levx = 680;
    levy = 60;
    for (int z=0;z<arrLevels.length;z++) {
      int level = arrLevels[z];
      
      // next line 
     if (level==21) { levy += 30; levx = 680+80; }
       
      btnSize = 45;
      if (level<42) btnSize=20;
      
      
      
      fill(80,80,80);
      rect(levx,levy,btnSize-4,20);
      
      String tx = ""+level;
      if (level==42) tx = "save";
      if (level==43) tx = "clear";
      if (level==44) tx = "copy";
      if (level==45) tx = "paste";
      fill(255);
      if (actualLevel==level) fill(255,0,0);
      
      textSize(14);
      if ((level<42)&&(level>9))textSize(10);
      text(tx,levx+4,levy+20);
      
      if (mousePressedHistory==false) {
       if (mousePressed) {
         if ((mouseX>levx)&&(mouseX<(levx+btnSize))) {
         
           if ((mouseY>levy)&&(mouseY<(levy+20))) {
             
             if (level<42) {
               // autosave?
               actualLevel = level;
               clearPlayfield();
               loadPlayfield();
             } else {
               if (level==42) storePlayfield();
               if (level==43) clearPlayfield();
               if (level==44) copyPlayfield();
               if (level==45) pastePlayfield();
             }
             
           }
         }
       }
     } 
     
     levx += btnSize;
     
    }
    
    

    
  
  
  // block
  text("BACKGROUND "+backgroundColor+"\nBORDERCOLOR "+borderColor,620,550+offsetRightY);
  
   }
  
  // background color selection
  if (false)
  for (int z=0;z<2;z++) {
  
    for (int h=0;h<16;h++) {
  
       Color aco =  getColor(h);
        
      int acolSizeX = 20;
      int acolSizeY = 20;
         
      int acolX = 10 + h*(acolSizeX+4);
      int acolY = 670+z*30+5+offsetRightY;
   
           // color ... 
         //   int paintColor = 25;
         
         if (mousePressed) {
           if ((mouseX>(acolX))&&(mouseX<(acolX+acolSizeX))) {
           
             if ((mouseY>(acolY-acolSizeY/2))&&(mouseY<(acolY+acolSizeY/2))) {
                  // change old color to 42
                  // change change new color to 43
                  // replace now invers ... 
                  /*
                  for (int i=0;i<256;i++) {
                    Block ozy = arrBlocks[i];
                    ozy.changeColor( backgroundColor, 42 );
                    ozy.changeColor( h, 43 );
                    ozy.changeColor( 42, h );
                    ozy.changeColor( 43, backgroundColor );
                  }
                  */
                  
                 if (z==0) backgroundColor = h;
                
                if (z==1) borderColor = h;
                
                 // changeDone();
                 // storePlayfield();
             }      
           }
         }
         
         fill(aco.r, aco.g, aco.b);
         if ((z==0)&&(backgroundColor==h)) {
             fill(255,0,0);
             circle(acolX+acolSizeX/2,acolY+4,acolSizeX+4); 
         }
          if ((z==1)&&(borderColor==h)) {
             fill(255,0,0);
             circle(acolX+acolSizeX/2,acolY,acolSizeX+4); 
         }
         fill(aco.r, aco.g, aco.b);
         circle(acolX+acolSizeX/2,acolY+4,acolSizeX);
          
         
     }
  }
  
  // tiles/blocks
  textSize(10);   
  
  
  
  // show blocks
  
  
  
  int blockX = posX + 298;
  int blockY = posY + 50;
  int blockSize = 32;
  
  fill(255,255,255,100);
  rect(blockX-1,blockY-1,blockSize*8+2,500);
  
  for (int x=0;x<256;x++) {
    fill(255);
    int sizeBlockX = 8;
    int t = blockX + (x%sizeBlockX)*blockSize;
    int tt = blockY + PApplet.parseInt(x/sizeBlockX)*blockSize;
    // rect(t,tt,blockSize,blockSize);
    
    Block ozy = arrBlocks[x];
    drawBlock(0, ozy, t, tt, blockSize/8/2, blockSize/16);
    
    // ...
    /*
    if (x==0) {
      stroke(124);
      line(t,tt,t+blockSize,tt+blockSize);
      line(t,tt+blockSize,t+blockSize,tt);
    }
    */
       
    if (x==selectedBlock) {
      fill(256,0,0);
      rect(t,tt,5,5);
      rect(t+blockSize-5,tt,5,5);
    }
     // interaction
     if (mousePressed) {
       if ((mouseX>t)&&(mouseX<(t+blockSize))) {
       
         if ((mouseY>tt)&&(mouseY<(tt+blockSize))) {
            selectedBlock = x;
         }      
       }
     }

  }
  
  
  // draw actual block
  int selectedBlockX = 10;
  int selectedBlockY = posY + 50;
  
  fill(255);
  
  stroke(255);
  
   int sizeX= 256;
  int sizeY= 256;
  
  // rect( selectedBlockX, selectedBlockY, sizeX,sizeY );
  
   // draw for segments ...
   // get block 
   // get segment
   // selectedSegment
   
   // Block blockXY = arrBlocks[selectedBlock];
   
   // draw block
   selectedSegment=0;
   
   int segmentX = selectedBlockX;
   int segmentY = selectedBlockY;
   
   int esegmentSizeX = sizeX/2/8/2*2;
   int esegmentSizeZ = sizeY/2/16*2;
   
  
   Block blockXY = arrBlocks[selectedBlock]; // 
   Segment segmentTmp = blockXY.arrSegments[selectedSegment]; // selectedSegment
   
   // pixel editor
   color(150,150,150,100);
   rect(segmentX-2,segmentY-2,sizeX+4,sizeY+4);
   
   drawBlock( 5, blockXY, segmentX, segmentY, esegmentSizeX,esegmentSizeZ);
   if ((mouseX<400) && (mouseY<400)) {
   if (toolSelected=="f") {
     text("fill",mouseX+20,mouseY+10);
   }}
   
   
   // draw tools
  
   int ux = selectedBlockX;
   int uy = segmentY+260;
  
   for (int z=0;z<arrToolsName.length;z++) {
     String toolx = arrToolsName[z];
     String toolxcode = arrTools[z];
     
    int toolsizeX = 50;
    int toolsizeY = 20;
    
     if (toolx=="nl") {
       ux = 10;
       uy +=toolsizeY+2;
       continue; 
     }
     
     if (mousePressedHistory==false) {
     if (mousePressed) {
       if ((mouseX>ux)&&(mouseX<(ux+toolsizeX))) {
       
         if ((mouseY>uy)&&(mouseY<(uy+toolsizeY))) {
            print(toolx);
            if (toolxcode=="d") toolSelected = toolxcode;
            if (toolxcode=="f") toolSelected = toolxcode;
            if (toolxcode=="c") {
              print("clear");
              
              Block blockXYT = arrBlocks[selectedBlock]; // 
              blockXYT.clear();
              
              changeDone();

            }
            if (toolxcode=="r") {
              print("random");
              
              Block blockXYT = arrBlocks[selectedBlock]; // 
              blockXYT.randIt();
              
              changeDone();

            }
 
            if (toolxcode=="left") {
               // storePlayfield(); 
               // saveBlocks();
            }
            
            // <> v^
            if (toolxcode=="flx") {
              print("flipx");
              
              // ok ... 
              Block blockXYT = arrBlocks[selectedBlock]; // 
              Block tempXY = new Block();
              initBlock(tempXY);
             
              for (int x=0;x<16;x++) {
                 for (int y=0;y<16;y++) {
                       tempXY.setBlockPixel(x,y, blockXYT.getBlockPixel(x,y));  
                 }
              }
              
              for (int x=0;x<16;x++) {
                 for (int y=0;y<16;y++) {
                       blockXYT.setBlockPixel(15-x,y, tempXY.getBlockPixel(x,y));  
                 }
              }
              
              
              
               changeDone();
               delay(50);
            }
            if (toolxcode=="fly") {
              print("flipy");
              
              // ok ... 
              Block blockXYT = arrBlocks[selectedBlock]; // 
              Block tempXY = new Block();
              initBlock(tempXY);
             
              for (int x=0;x<16;x++) {
                 for (int y=0;y<16;y++) {
                       tempXY.setBlockPixel(x,y, blockXYT.getBlockPixel(x,y));  
                 }
              }
              
              for (int x=0;x<16;x++) {
                 for (int y=0;y<16;y++) {
                       blockXYT.setBlockPixel(x,15-y, tempXY.getBlockPixel(x,y));  
                 }
              }
              
               changeDone();
               
               delay(50);

            }
            
            if (toolxcode=="ml") {
              print("moveleft");
              
              // ok ... 
              Block blockXYT = arrBlocks[selectedBlock]; // 
              Block tempXY = new Block();
              initBlock(tempXY);
             
              for (int x=0;x<16;x++) {
                 for (int y=0;y<16;y++) {
                       tempXY.setBlockPixel(x,y, blockXYT.getBlockPixel(x,y));  
                 }
              }
              
              for (int x=0;x<16;x++) {
                 for (int y=0;y<16;y++) {
                   if (x==15) {
                     blockXYT.setBlockPixel(15,y, tempXY.getBlockPixel(0,y)); 
                   } else
                   {
                       blockXYT.setBlockPixel(x,y, tempXY.getBlockPixel(x+1,y));  
                   }
                 }
              }
               delay(30);
             
               changeDone();
            }
            
            // moves
            if (toolxcode=="mu") {
              print("moveup");
              
              // ok ... 
              Block blockXYT = arrBlocks[selectedBlock]; // 
              Block tempXY = new Block();
              initBlock(tempXY);
             
              for (int x=0;x<16;x++) {
                 for (int y=0;y<16;y++) {
                       tempXY.setBlockPixel(x,y, blockXYT.getBlockPixel(x,y));  
                 }
              }
              
              for (int x=0;x<16;x++) {
                 for (int y=0;y<16;y++) {
                   if (y==15) {
                     blockXYT.setBlockPixel(x,15, tempXY.getBlockPixel(x,0)); 
                   } else
                   {
                       blockXYT.setBlockPixel(x,y, tempXY.getBlockPixel(x,y+1));  
                   }
                 }
              }
              delay(30);
               changeDone();
            }
            
            // copy
            // copypasteBlock
            if (toolxcode=="cp") {
              Block blockXYT = arrBlocks[selectedBlock]; // 
              copypasteBlock.updateFrom(blockXYT);
              changeDone();
            }
            
            if (toolxcode=="pa") {
              print("paste");
              Block blockXYT = arrBlocks[selectedBlock]; // 
              blockXYT.updateFrom(copypasteBlock);
              changeDone();
            }
            
            // <> v^
            if (toolxcode=="ro") {
              print("rotate");
              
              // ok ... 
              Block blockXYT = arrBlocks[selectedBlock]; // 
              Block tempXY = new Block();
              initBlock(tempXY);
              
              // copy
              for (int x=0;x<8;x++) {
                 for (int y=0;y<16;y++) {
                       tempXY.setBlockPixel(x,y, blockXYT.getBlockPixel(x,y));  
                 }
              }
              
              // rotate 
              for (int x=0;x<8;x++) {
                 for (int y=0;y<16;y++) {
                   
                    float t = x*2-7;
                    float tt = y-7;
                    
                    float alpha = atan2(tt,t);
                    alpha += 0.5f*PI;
                    
                    float r = sqrt( t*t + tt*tt );
                    
                    float fx = r * cos(alpha)+8.0f;
                    float fy = r * sin(alpha)+8.0f;
                    
                    if (fx<0) fx = 0;
                    if (fy<0) fy = 0;
                    if (fx>16) fx = 15;
                    if (fy>16) fy = 15;
                    
                    int o = tempXY.getBlockPixel(x,y);
                    blockXYT.setBlockPixel( PApplet.parseInt(fx/2),PApplet.parseInt(fy),o );  
                 }
              }
              
               changeDone();
            }
            
            
         }      
       }
     }
     }
     
     fill(50);
     rect(ux,uy,toolsizeX,20);
     fill(255);
     if (toolSelected==toolxcode) fill(255,0,0);
     textSize(16);
     text(toolx,ux,uy+16);  
     
     ux = ux+toolsizeX+4;
     
 }
   
   // colors
   
   int colorLine = 8;
   
   for (int h=0;h<amountColors;h++) {

     Color co =  getColor(h);
      
    int colSizeX = 30;
    int colSizeY = 30;
       
    int colX = segmentX + h%colorLine*(colSizeX+2);
    int colY = segmentY+esegmentSizeZ + 340 + PApplet.parseInt(h/colorLine)*(colSizeY+2);
 
    
         // color ... 
       //   int paintColor = 25;
       
       if (mousePressed) {
         if ((mouseX>colX)&&(mouseX<(colX+colSizeX))) {
         
           if ((mouseY>colY)&&(mouseY<(colY+colSizeY))) {
              paintColor = h;
           }      
         }
       }
       
       fill(co.r, co.g, co.b);
       if (h==paintColor) {
           fill(255,0,0);
           rect(colX-3,colY-3,colSizeX+6,colSizeY+6); 
       }
       fill(co.r, co.g, co.b);
       rect(colX,colY,colSizeX,colSizeY);
        
   }
   
   // colors and colorfield ...
   // bitsPerColor
   int colordefsx = 10;
   int colordefsy = 600;
   
   Color coz = c64ColorRGB[paintColor];
   
   for (int kraftwerk=0;kraftwerk<3;kraftwerk++) {
   
      int colSizeY = 20;
      int colY = colordefsy + kraftwerk*colSizeY;
     
     // now forward
     for (int z=0;z<Math.pow(2,bitsPerColor);z++) {
        
       int r=128;
       int g=0;
       int b=0;
       if (kraftwerk==1) { r=0; b=0; g=128; }
       if (kraftwerk==2) { r=0; b=128; g=0; }
       
       // c64ColorRGB[0]
       
       fill(r, g, b);
       
       int max = coz.systemR;
       if (kraftwerk==1)  max = coz.systemG;     
       if (kraftwerk==2)  max = coz.systemB;     
       
       if (z>max) fill(20, 20, 20);
         
        int colSizeX = 15;
           
        int colX = colordefsx + z*colSizeX;
       
       
         if (mousePressed) {
           if ((mouseX>colX)&&(mouseX<(colX+colSizeX))) {
           
             if ((mouseY>colY)&&(mouseY<(colY+colSizeY))) {
                if (kraftwerk==0) coz.systemR = z;
                if (kraftwerk==1) coz.systemG = z;
                if (kraftwerk==2) coz.systemB = z;
                coz.updateGlobalColors();
             }      
           }
         }       
       
         rect(colX,colY,colSizeX-1,colSizeY-1);
         
         
         
       
     }
     
     fill(255, 255, 255);
     int val = coz.systemR;
     if (kraftwerk==1) val = coz.systemG;
     if (kraftwerk==2) val = coz.systemB;     
     text(val,colordefsx+16*15+10,colY+12);
     
   }
   
   
   
   // colorfield
   // {-1,-1,-1,-1},
   if (false)
   for (int u=0;u<5;u++) {
    for (int uu=0;uu<5;uu++) {
        int col = arrColorfield[uu][u];
       
         if (col!=-1) {
                 
               Color co = getColor(col);
           
              fill(co.r, co.g, co.b);
         
              int colSizeX = 30;
              int colSizeY = 30;
                 
              int colX = segmentX + 90 + u*(colSizeX+2);
              int colY = segmentY+esegmentSizeZ+320 + uu*(colSizeY+2);
          
               rect(colX,colY,colSizeX,colSizeX);
       
             if (mousePressed) {
             if ((mouseX>colX)&&(mouseX<(colX+colSizeX))) {
             
               if ((mouseY>colY)&&(mouseY<(colY+colSizeY))) {
                  paintColor = col;
               }      
             }
           }
           
           if (col==paintColor) {
               fill(255,0,0);
               rect(colX-3,colY-3,colSizeX+6,colSizeY+6); 
           }
           
           fill(co.r, co.g, co.b);
           rect(colX,colY,colSizeX,colSizeY); 
       
       }
     
    }
    
    mousePressedHistory = mousePressed;
    
   }
   
   // draw info
   fill(0);
   rect(0,700,300,200);
   
   fill(255);
   String str = "INFO: "+selectedBlock+"\n\nEXPORTED BLOCKS: "+blocksASMAmount;
   
       
  
   Block blockXYSelected = arrBlocks[selectedBlock]; //

   // all the colors 
/*   
   str += "\n"+blockXYSelected.arrSegments[0].getColorNumbers();
   str += "\n"+blockXYSelected.arrSegments[1].getColorNumbers();
   str += "\n"+blockXYSelected.arrSegments[2].getColorNumbers();
   str += "\n"+blockXYSelected.arrSegments[3].getColorNumbers();
*/        
   textSize(12);
   text(""+str,10,720);
   
   // draw field ... 
 
   int playfieldX = selectedBlockX + 600;
   int playfieldY = posY + 50;
   
   int playfieldSizeX = 8;
   int playfieldSizeY = 4;
   
   int playfieldSizeXSegment = 32;
   int playfieldSizeYSegment = 32;
   
   int fieldSize = 20;
   
   Color sdcox = getColor(borderColor);
   fill(sdcox.r, sdcox.g, sdcox.b);
   // rect(playfieldX-10,playfieldY-10+offsetRightY,playfieldSizeXSegment*20+2+20,playfieldSizeYSegment*13+2+20);
   
   fill(255,255,255,100);
   // rect(playfieldX-1,playfieldY-1+offsetRightY,playfieldSizeXSegment*20+2,playfieldSizeYSegment*13+2);
   
   if (false)
   for (int o=0;o<320;o++) {
     int fieldT = arrPlayfield[o];
     int x = playfieldX + (o%fieldSize)*playfieldSizeXSegment;
     int y = playfieldY + PApplet.parseInt(o/fieldSize)*playfieldSizeYSegment+offsetRightY;
     
     // fieldT = 1;
     
     Block blockXYP = arrBlocks[fieldT];
     drawBlock( 0, blockXYP, x, y, playfieldSizeXSegment/4/2/2,playfieldSizeYSegment/8/2);
     
     // rect(x,y,playfieldSizeXSegment,playfieldSizeYSegment);
   
     if (mousePressed) {
       if ((mouseX>=x)&&(mouseX<(x+esegmentSizeX*2))) {
       
         if ((mouseY>=y)&&(mouseY<(y+playfieldSizeYSegment))) {
            arrPlayfield[o] = selectedBlock;
            
            // startXFocus
            startXFocus = o%fieldSize - 9;
            startYFocus = PApplet.parseInt(o/fieldSize) - 4;
            
            if (startXFocus<0) startXFocus = 0;
            
            if (startYFocus<0) startYFocus = 0;
            
         }      
       }
     }
   
    
   
   
 }
 
 

   // 
   // draw focus
   // 
 
   int iplayfieldX = selectedBlockX + 600;
   int iplayfieldY = posY + 580;
   
   int iplayifieldSizeX = 8;
   int iplayifieldSizeY = 4;
   
   int iplayifieldSizeXSegment = 48;
   int iplayifieldSizeYSegment = 48;
   
   int ifieldSize = 20;
   
   Color isdcox = getColor(borderColor);
   fill(isdcox.r, isdcox.g, isdcox.b);
   // rect(iplayfieldX-10,iplayfieldY-10+offsetRightY,iplayifieldSizeXSegment*20+2+20,iplayifieldSizeYSegment*13+2+20);
   
   fill(255,255,255,100);
   // rect(iplayfieldX-1,iplayfieldY-1+offsetRightY,iplayifieldSizeXSegment*20+2,iplayifieldSizeYSegment*13+2);
   
   
   int offsetX = startXFocus;
   int offsetY = startYFocus;
   
   if (false)
   for (int o=0;o<320;o++) {
     
     
     int xx = o%ifieldSize;
     int yy = PApplet.parseInt(o/ifieldSize);
     
     
     int fieldT = arrPlayfield[o];
     int x = iplayfieldX + ((o%ifieldSize)-offsetX)*iplayifieldSizeXSegment;
     int y = iplayfieldY + (PApplet.parseInt(o/ifieldSize)-offsetY)*iplayifieldSizeYSegment+offsetRightY;
     
     if (xx<startXFocus) continue;
     if (yy<startYFocus) continue;
     
  
     
     // fieldT = 1;
     
     Block blockXYP = arrBlocks[fieldT];
     drawBlock( 0, blockXYP, x, y, iplayifieldSizeXSegment/4/2/2,iplayifieldSizeYSegment/8/2);
     
   
 }
 
 textSize(18);
 fill(200,200,200);
 text(msg,1100,20);
}

public void keyPressed()
{
  //if(key == CODED)
 // {
    if ((keyCode == LEFT) || (key == 'a'))
    {
      startXFocus -= 1;  
    }
    if ((keyCode == RIGHT) || (key == 'd'))
    {
      startXFocus += 1;  
    }
    
    if ((keyCode == UP) || (key == 'w'))
    {
      startYFocus -= 1;  
    }
    
    if ((keyCode == DOWN) || (key == 's'))
    {
      startYFocus += 1;  
    }
    
    
    
  //}
}


public void drawBlock(int modex, Block blockXY, int segmentX, int segmentY, int segmentSizeX, int segmentSizeZ) {
 
  //if (editorMode==1) {
    fill(255,255,255);
    rect(segmentX,segmentY,2,2);
  // }
  
   drawSegment(modex, blockXY.arrSegments[0],segmentX,segmentY,segmentSizeX,segmentSizeZ);
 
  
  //if (blockXY.arrSegments[0].colorsAreTrue||blockXY.arrSegments[1].colorsAreTrue||blockXY.arrSegments[2].colorsAreTrue||blockXY.arrSegments[3].colorsAreTrue) {
  fill(200,0,0);
  if (modex==5) {
    color(30); 
    fill(30);
    // rect(segmentX,segmentY,10,10);
    stroke(255,255,255,100);   
    line(segmentX+segmentSizeX*8,segmentY, segmentX+segmentSizeX*8,segmentY+segmentSizeZ*16);
    line(segmentX,segmentY+segmentSizeZ*8, segmentX+segmentSizeX*16,segmentY+segmentSizeZ*8);
    noStroke();  
  }
//}

  // block value
  // text(""+blockXY.index,segmentX,segmentY);
  if (blockXY.index==8) {
      stroke(255,0,0);
      int blockSize = segmentSizeX*8;
      // line(segmentX,segmentY,segmentX+blockSize,segmentY+blockSize);
      // line(segmentX,segmentY+blockSize,segmentX+blockSize,segmentY);
  }
}



// mode = 0 // print | mode=5 interactive
public void drawSegment(int modex, Segment segmentTmp, int segmentX, int segmentY, int segmentSizeX, int segmentSizeZ) {

   fill(255);
   
   for (int z=0;z<16;z++) {
     for (int zz=0;zz<16;zz++) {
         int fx = segmentX + z*segmentSizeX;
         int fy = segmentY + zz*segmentSizeZ;
         
         if (modex==5) {
    
           // color ... 
           
           
           if (mousePressed ) {
             if ((mouseX>=fx)&&(mouseX<(fx+segmentSizeX))) {
             
               if ((mouseY>=fy)&&(mouseY<(fy+segmentSizeZ))) {

                  println("draw() "+z+" "+zz+"   "+paintColor);

                   // fill? 
                   
                   if (toolSelected=="d") {
                     segmentTmp.arrColors[zz*16+z].c64Color = paintColor;
                     print("draw");
                     // changeDone();
                   }
                   
                   // existing color?
                   if (toolSelected=="f" && !mousePressedHistory) {
                     
                     // print("fill now "+fx+","+fy+"\n");
                     
                     int actColor = segmentTmp.getPixel(z,zz);
                     // turn into special color 
                     // 42
             
                     if (actColor==paintColor) return;
             
                     
                     segmentTmp.setPixel(z,zz,42);
                     
                     int breaker = 0;
                      
                     // recursive change ...
                     boolean goon = true;
                     do {
                       
                       boolean foundit = false;
                       
                       for (int j=0;j<16;j++) {
                         for (int jj=0;jj<16;jj++) {
                            // 4 * 8
                            int v = segmentTmp.getPixel(j,jj);
                            if (v==42) {
                               segmentTmp.setPixel(j,jj,paintColor);
                               
                               // create more ... 
                               if (j>0)
                               if (segmentTmp.getPixel(j-1,jj)==actColor) {
                                 segmentTmp.setPixel(j-1,jj,42);
                               }
                               
                               if (j<15)
                               if (segmentTmp.getPixel(j+1,jj)==actColor) {
                                 segmentTmp.setPixel(j+1,jj,42);
                               }
                               if (jj>0)
                               if (segmentTmp.getPixel(j,jj-1)==actColor) {
                                 segmentTmp.setPixel(j,jj-1,42);
                               }
                               if (jj<15)
                               if (segmentTmp.getPixel(j,jj+1)==actColor) {
                                 segmentTmp.setPixel(j,jj+1,42);
                               }
                               foundit = true;
                               // break; 
                            }
                            
                            
                            
                            
                            
                         }  
                         // if (foundit) break; 
                       }
                       
                       
                       int count = 0;
                       for (int j=0;j<16;j++) {
                         for (int jj=0;jj<16;jj++) {
                            // 4 * 8
                            if (segmentTmp.getPixel(j,jj)==42) {
                              // print("found: "+j+"/"+jj);
                              count++;
                            }
                         }
                       }
                       
                       if (count==0) 
                       goon = false;
                       
                       
                     
                   } while(goon);
                     
                      changeDone();
                      
                   }
                 
                   
                  
                  
               }      
             }
           }
           
         }
         
         C64Color col = segmentTmp.arrColors[zz*16+z];
        
         if (col==null) continue;
         
        // ...
        // fill(200);
        // col.setFillColor();
        col.setFillColor();
         
         color(col.c64Color*10);
         Color co = getColor(col.c64Color);
         fill(co.r, co.g, co.b);
         
         rect(fx,fy,segmentSizeX,segmentSizeZ);
         noStroke();
         // line(fx,fy,fx+segmentSizeX,fy);
         
         
     }
     
     int fxx = segmentX + 0*segmentSizeX;
     int fyy = segmentY + 0*segmentSizeZ;
      
      if (modex==5) {
        fill(255);
        textSize(12);
        int zx = -9;
        int zy = -5;
        if (segmentX>100) zx = segmentSizeX*4+5;
        fill(255);
        if (segmentTmp.colorCounter>3) fill(255,0,0);
        text(""+segmentTmp.colorCounter,fxx+zx,fyy+12+zy);
      }    
         
   }
   
       if (editorMode==1) {
         //  fill(255,255,255);
         //  rect(segmentX,segmentY,3,3);
          // rect(segmentX+segmentSizeX*8,segmentY+segmentSizeZ*8,-3,-3);
           
         }
  
}

// JSON STORE/LOAD

// actual level

int actualLevel = 0;

public void loadPlayfield() {
  
  println("loadPlayfield()");
  
  JSONArray arrValues =  new JSONArray();
  
  // file exists?
   File f = null;
   boolean bool = false;

   String filename = "level"+actualLevel+".json";


    // create new files
    f = new File(filename);
    println("existing: "+f.exists());
    if (!f.exists()) {
       println("sorry couldn't find file "+filename);
     // return;
    }
   

  try {
    
    arrValues = loadJSONArray(filename);
  
    int tileIndex = 0;
    
    for (int i = 0; i < arrValues.size(); i++) {
        
      JSONObject tile = arrValues.getJSONObject(i); 
      int z = tile.getInt("attribute");
      if (z==1) {
        try {
            backgroundColor = tile.getInt("background");
        } catch(Exception e) {
        
        }
        
         try {
            borderColor = tile.getInt("border");
        } catch(Exception e) {
        
        }
      }
      
      if (z==0) {
         arrPlayfield[tileIndex] = tile.getInt("tile"); 
         
         if (importC64DataActive) {
             // Big A-Z
             int impD = arrPlayfield[tileIndex];
             if (impD>=14 && impD<=39) {
               arrPlayfield[tileIndex] = impD-1; 
             }
             if (impD>=40 && impD<=49) {
               arrPlayfield[tileIndex] = impD-1; 
             }
         }
         
         // println("nextplayfield "+tile.getInt("tile"));
         tileIndex++;
      }
    }
  } catch( Exception e ) {
   
      println("could not open file");
  }

  

}

public void clearPlayfield() {
   for (int z=0;z<arrPlayfield.length;z++) {
     arrPlayfield[z]=0;
   }
}

public String digitUp( int z ) {
  
  String res = ""+z;
  
  if (z<10) res = "0"+res;
  
  return res;
  
}

public void storePlayfield() {
  
  msg = "Playfield stored "+hour()+":"+digitUp(minute());
  
  println("storePlayField()");
  /*
  JSONObject json;
  json = new JSONObject();
  */
  
  JSONArray arrValues =  new JSONArray();
  
  // add size
  // add backgroundcolor
  // add border color
  
  int startIndex = 0;
  
  JSONObject background = new JSONObject();
  background.setInt("background", backgroundColor);
  background.setInt("attribute", 1);
  arrValues.setJSONObject(startIndex, background);
  startIndex++;
  
  JSONObject border = new JSONObject();
  border.setInt("border", borderColor);
  border.setInt("attribute", 1);
  arrValues.setJSONObject(startIndex, border);
  startIndex++;

  JSONObject wjson = new JSONObject();
  wjson.setInt("width", 20);
  wjson.setInt("attribute", 1);
  arrValues.setJSONObject(startIndex, wjson);
  startIndex++;
 
  JSONObject wheight = new JSONObject();
  wheight.setInt("width", 13);
  wheight.setInt("attribute", 1);
  arrValues.setJSONObject(startIndex, wheight);
  startIndex++;
  
  
  for (int i = 0; i < arrPlayfield.length; i++) {
  
      JSONObject tile = new JSONObject();
  
      tile.setInt("tile", arrPlayfield[i]);
       tile.setInt("attribute", 0);
  
      arrValues.setJSONObject(startIndex+i, tile);
   }
   
  saveJSONArray(arrValues, "level"+actualLevel+".json"); 
  
  // level 
  PrintWriter output = createWriter("level"+actualLevel+".s"); 

  output.println("level_"+actualLevel+":");
 
  for (int i = 0; i < arrPlayfield.length; i++) {
    // 20
    if (i%20==0) {
       output.print("\n             dc.b ");  
    }
    output.print(arrPlayfield[i]);
    if (i%20!=19)
    output.print(",");
  }
  
  println("Data-Saved: "+arrPlayfield.length);
  
  
  output.println("\nlevel_"+actualLevel+"_colors:");
  output.println("\t\t      dc.b "+backgroundColor+","+borderColor);
  
  
  output.flush(); // Writes the remaining data to the file
  output.close();
  
}

// load and save block
public void loadBlocks()  {

    msg = "Load blocks "+hour()+":"+digitUp(minute());


  println("loadBlocks()");
  
  JSONArray arrValues =  new JSONArray();
  
  // file exists?
   File f = null;
   boolean bool = false;

    String filename = "bobs1616.json";

    try {
    
    // create new files
    f = new File(filename);
    // println("existing: "+f.exists());
    if (!f.exists()) {
       println("sorry couldn't find file "+filename);
     // return;
    }
  
    arrValues = loadJSONArray(filename);
  
 
  // add 4 segmensts
  for (int z=0;z<256;z++) {
    Block blo = arrBlocks[z];
    blo.index = z;
    //println(blo);
    int s=0;
      
      Segment seg = blo.arrSegments[s];
   // println(seg);
 
      // dirty junk junk
      for (int c=0;c<256;c++) {
          JSONObject tile = arrValues.getJSONObject(z*256+s*32+c); 
          seg.arrColors[c].c64Color = tile.getInt("color");
      }
     
  } 
  
    } catch( Exception e ) {
      
    }
    
   loadColors();
}


public void saveBlocks()  {

    msg = "Bobs stored "+hour()+":"+digitUp(minute());


  // println("saveBlocks()");
  
  JSONArray arrValues =  new JSONArray();
  
  // add 4 segmensts
  for (int z=0;z<256;z++) {
    Block blo = arrBlocks[z];
    //println(blo);
      Segment seg = blo.arrSegments[0];
   // println(seg);
 
      // dirty junk junk
      for (int c=0;c<256;c++) {
         int col = seg.arrColors[c].c64Color;
          // println(col);
 
         // 256 * 32
         JSONObject pixel = new JSONObject();
         pixel.setInt("color", col);
           arrValues.setJSONObject(z*256+c, pixel);
      }
     
  }
 
  saveJSONArray(arrValues, "bobs1616.json"); 
  
  // save the blocks
  // level 
  PrintWriter output = createWriter("bobs1616all.s"); 

  output.println("bobs1616:");
 
  
  // add 4 segmensts ; blocksASMAmount
  for (int z=0;z<blocksASMAmount;z++) {
 
    println("block "+z+":");
    output.println("\nbob1616_"+z+":");
 

    Block blo = arrBlocks[z];
    //println(blo);
    int s=0;
 
      // output.println("bob"+z+"_"+s+":");
 
      Segment seg = blo.arrSegments[s];
      
      // output.print("\t\t.byte "+seg.getColorNumbersAsm()); 
      output.print(seg.getColorNumbersAsm());
      
      // output the mask
      output.println("bob1616_"+z+"_mask:");
      // seg
      for (int i=0;i<16;i++) {
        output.print("\n\t\t dc.w %");
        for (int ii=0;ii<16;ii++) {
           if (seg.arrColors[i*16+ii].c64Color>0) {
             output.print("1");  
           } else {
             output.print("0");  
           }
        }
        output.print(",0");
      }

      // output.print("\n");

  }

  
  output.flush(); // Writes the remaining data to the file
  output.close();
 
 
  // save colors too
  saveColors();
  
  
}
      public void saveColors() {
        
        JSONArray arrValues =  new JSONArray();
  
  
        for (int o=0;o<32;o++) {
            Color coz = c64ColorRGB[o];        
             JSONObject colorX = new JSONObject();
             colorX.setInt("r", coz.systemR);
             colorX.setInt("g", coz.systemG);
             colorX.setInt("b", coz.systemB);
             arrValues.setJSONObject(o, colorX);
        }
       
        saveJSONArray(arrValues, "colors.json");  
       
        // now save as assembler .s file
        
        
        // colors
          PrintWriter output = createWriter("colors.s"); 
          
          

          // output.println("colors:");
          
          String strAs = "";
          
          // how many bitplanes ... 
          for (int o=0;o<32;o++) {
            Color coz = c64ColorRGB[o];        
             JSONObject colorX = new JSONObject();
             int val = coz.systemR; if (val>15) val=0;
             strAs += "$0"+Integer.toHexString(val);
             val = coz.systemG; if (val>15) val=0;
             strAs += ""+Integer.toHexString(val);
             val = coz.systemB; if (val>15) val=0;
             strAs += ""+Integer.toHexString(val);
             strAs += ",";
          }
          
          output.println("\t\t      dc.w "+strAs+"$0");
          
          
          output.flush(); // Writes the remaining data to the file
          output.close();

          // println("-----"+Integer.toHexString(15));
        
  }
  
  public void loadColors() {
     
    JSONArray arrValues =  new JSONArray();
  
  // file exists?
   File f = null;
   boolean bool = false;

    String filename = "colors.json";

    try {
    
    // create new files
    f = new File(filename);
    // println("existing: "+f.exists());
    if (!f.exists()) {
       println("sorry couldn't find file "+filename);
     // return;
     arrValues = loadJSONArray(filename);
 
    // add 4 segmensts
    for (int z=0;z<32;z++) {
       
        Color coz = c64ColorRGB[z];
        
        JSONObject colorx = arrValues.getJSONObject(z); 
        coz.systemR = colorx.getInt("r");
        coz.systemG = colorx.getInt("g");
        coz.systemB = colorx.getInt("b");
        coz.updateGlobalColors();
      }
    }
    } catch( Exception e ) {
      
    }
    
  }

 public void changeDone() {
   // saveBlocks();
 }
 
 public void copyPlayfield() {

    for (int z=0;z<arrPlayfield.length;z++) {
      arrCopyPastePlayfield[z]  = arrPlayfield[z];
    }
   
    ibackgroundColor = backgroundColor;
    iborderColor = borderColor;
    
 }
 
 public void pastePlayfield() {
 
      for (int z=0;z<arrPlayfield.length;z++) {
        arrPlayfield[z] = arrCopyPastePlayfield[z];
    }
 
    backgroundColor = ibackgroundColor;
    borderColor = iborderColor;
 
   
 }
 


  public void settings() { size(1280, 864); }

  static public void main(String[] passedArgs) {
    String[] appletArgs = new String[] { "sketch_AmigaBOB1616Editor" };
    if (passedArgs != null) {
      PApplet.main(concat(appletArgs, passedArgs));
    } else {
      PApplet.main(appletArgs);
    }
  }
}
