#@name pacman
@inputs 
@outputs EGPN
@persist EGPN EGP:wirelink R C MazeTable:table Rect:table Merger Merged:table
@trigger 

if (first()) {
    Maze = "
    # # # # # # # # # # # # # # # # # # # # # # #
    # . . . . . . . . . . # . . . . . . . . . . #
    # . # # # . # # # # . # . # # # # . # # # . #
    # . # # # . # # # # . # . # # # # . # # # . #
    # . . . . . . . . . . . . . . . . . . . . . #
    # . # # # . # . # # # # # # # . # . # # # . #
    # . . . . . # . # # # # # # # . # . . . . . #
    # # # # # . # . . . . # . . . . # . # # # # #
    # # # # # . # # # # - # - # # # # . # # # # #
    # # # # # . # - - - - - - - - - # . # # # # #
    # # # # # . # - # # # - # # # - # . # # # # #
    T - - - - . - - # M M - M M # - - . - - - - T
    # # # # # . # - # # # # # # # - # . # # # # #
    # # # # # . # - - - - - - - - - # . # # # # #
    # # # # # . # - # # # # # # # - # . # # # # #
    # # # # # . # - # # # # # # # - # . # # # # #
    # . . . . . . . . . . # . . . . . . . . . . #
    # . # # # . # # # # . # . # # # # . # # # . #
    # . . . # . . . . . . P . . . . . . # . . . #
    # # # . # . # . # # # # # # # . # . # . # # #
    # . . . . . # . . . . # . . . . # . . . . . #
    # . # # # # # # # # . # . # # # # # # # # . #
    # . # # # # # # # # . # . # # # # # # # # . #
    # . . . . . . . . . . . . . . . . . . . . . #
    # # # # # # # # # # # # # # # # # # # # # # #
    ":replaceRE("%s+", "")
    
    MazeTable = table()
    for (I = 0, 24) {
        local Sub = Maze:sub(I*23 + 1, I*23 + 23)
        MazeTable[I + 1, array] = Sub:explode("")
    }
    
    EGP = entity():isWeldedTo():wirelink()
    EGP:egpClear()
    
    
#[    function mergeAll(array) {
  do {
     var newArr = [], didMerge = false, i = 0;

     while (i < array.length) {
        if (intersects(array[i], array[i+1]) {
          newArr.push(merge(array[i], array[i+1]));
          i++;
          didMerge = true;
        }
        i++;
     }
     array = newArr;
  } while (didMerge);
  return array;
}

function intersects(r1, r2) {
    return !( r2.x > r1.x+r1.w
           || r2.x+r2.w < r1.x
           || r2.y > r1.y+r1.h
           || r2.y+r2.h < r1.y
           );
}

function merge(r1, r2) {
   return { x: Math.min(r1.x, r2.x),
            y: Math.min(r1.y, r2.y),
            w: Math.max(r1.w, r2.w),
            h: Math.max(r1.h, r2.h)
          }]#
#}

    function number intersects( R1:vector2, R1S, R2:vector2, R2S ) {
        return !( 
            R2:x() > R1:x() + R1S | 
            R2:x() + R2S < R1:x() |
            R2:y() > R1:y() + R1S |
            R2:y() + R2S < R1:y() )
    }
    
    function number intersects( Rect1:array, Rect2:array ) {
        local Rect1Pos  = Rect1[1, vector2]
        local Rect1Size = Rect1[2, vector2]
        
        local Rect2Pos  = Rect2[1, vector2]
        local Rect2Size = Rect2[2, vector2]
    }
    
#[    function array merge( R1:vector2, R1S, R2:vector2, R2S ) {
        return array(
            vec2(min(R1:x(), R2:x()), min(R1:y(), R2:y())),
            max(R1S, R2S)
        )
    }]#
}

interval(15)

#if (egpCanSendUmsg()) {
    if (R < 5) {
        if (C < 23) {
            C++
            
            local D = MazeTable[R + 1, array][C, string]
            if (D == "#") {
                EGPN++
                
                local Pos = 
                
                Rect[EGPN, array] = array(vec2(C*12 + 7, R*12 + 7), 12)
                #EGP:egpBox(EGPN, vec2(C*12 + 7, R*12 + 7), vec2(12, 12))
            }
        }
        else {
            R++
            C = 0
        }
        
        if (R >= 5) {
            EGPN = 0
        }
    }
    else {
        
        DidMerge = 0
        while ( perf() & Merger < Rect:count() ) {
            Merger++
            
            local R1 = Rect[Merger, array]
            local R2 = Rect[Merger + 1, array]
#[            
            if (intersects(R1[1, vector2], R1[2, number], R2[1, vector2], R2[2, number])) {
               # Merged:pushArray(merge(R1[1, vector2], R1[2, number], R2[1, vector2], R2[2, number]))
                Merger++
                DidMerge = 1
            }]#
        }
        
        if (Merger >= Rect:count()) {
            if (EGPN < Merged:count() & egpCanSendUmsg()) {
               # EGPN++
                #EGP:egpBox(EGPN, Merged[EGPN, vector2], vec2(12, 12))
            }
        }
    }
#}


#[function mergeAll(array) {
  do {
     var newArr = [], didMerge = false, i = 0;

     while (i < array.length) {
        if (intersects(array[i], array[i+1]) {
          newArr.push(merge(array[i], array[i+1]));
          i++;
          didMerge = true;
        }
        i++;
     }
     array = newArr;
  } while (didMerge);
  return array;
}
]#
