//Copyright 2015 Erik De Rijcke
//
//Licensed under the Apache License,Version2.0(the"License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
//http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing,software
//distributed under the License is distributed on an"AS IS"BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
package org.westmalle.wayland.output;

import com.google.auto.factory.AutoFactory;
import com.sun.jna.ptr.IntByReference;
import org.freedesktop.pixman1.Pixman1Library;
import org.freedesktop.pixman1.pixman_box32;
import org.freedesktop.pixman1.pixman_region32;

import javax.annotation.Nonnull;
import javax.media.nativewindow.util.PointImmutable;
import javax.media.nativewindow.util.Rectangle;
import javax.media.nativewindow.util.RectangleImmutable;
import java.util.ArrayList;
import java.util.List;

@AutoFactory(className = "RegionFactory")
public class Region {

    private final pixman_region32 pixman_region32 = new pixman_region32();

    Region() {
    }

    public List<RectangleImmutable> asList() {
        //int pointer
        final IntByReference n_rects = new IntByReference();
        final pixman_box32 pixman_box32_array = Pixman1Library.INSTANCE.pixman_region32_rectangles(getPixmanRegion32(),
                                                                                                   n_rects);
        final int size = n_rects.getValue();
        final pixman_box32[] pixman_box32s = (pixman_box32[]) pixman_box32_array.toArray(size);

        final List<RectangleImmutable> boxes = new ArrayList<>(size);
        for (final pixman_box32 pixman_box32 : pixman_box32s) {
            final int x = pixman_box32.x1;
            final int y = pixman_box32.y1;

            final int width = pixman_box32.x2 - x;
            final int height = pixman_box32.y2 - y;
            boxes.add(new Rectangle(x,
                                    y,
                                    width,
                                    height));
        }
        return boxes;
    }

    public Region add(@Nonnull final RectangleImmutable rectangle) {
        //FIXME check result
        final int result = Pixman1Library.INSTANCE.pixman_region32_union_rect(getPixmanRegion32(),
                                                                              getPixmanRegion32(),
                                                                              rectangle.getX(),
                                                                              rectangle.getY(),
                                                                              rectangle.getWidth(),
                                                                              rectangle.getHeight());

        return this;
    }

    public Region subtract(@Nonnull final RectangleImmutable rectangle) {
        final pixman_region32 delta_pixman_region32 = new pixman_region32();
        Pixman1Library.INSTANCE.pixman_region32_init_rect(delta_pixman_region32,
                                                          rectangle.getX(),
                                                          rectangle.getY(),
                                                          rectangle.getWidth(),
                                                          rectangle.getHeight());
        //FIXME check result
        final int result = Pixman1Library.INSTANCE.pixman_region32_subtract(getPixmanRegion32(),
                                                                            getPixmanRegion32(),
                                                                            delta_pixman_region32);
        return this;
    }

    public boolean contains(final PointImmutable point) {
        for (final RectangleImmutable rectangle : asList()) {
            final int x1 = rectangle.getX();
            final int y1 = rectangle.getY();

            final int x2 = x1 + rectangle.getWidth();
            final int y2 = y1 + rectangle.getHeight();

            final int pointX = point.getX();
            final int pointY = point.getY();
            if (x1 <= pointX && pointX <= x2 && y1 <= pointY && pointY <= y2) {
                return true;
            }
        }
        return false;
    }

    public pixman_region32 getPixmanRegion32() {
        return this.pixman_region32;
    }
}

@@ -3948,152 +3948,174 @@
     
-for (final RectangleImmutable rectangle : asList()) %7B%0A            final int x1 = rectangle.getX();%0A            final int y1 = rectangle
+return Pixman1Library.INSTANCE.pixman_region32_contains_point(getPixmanRegion32(),%0A                                                                      point
 .get
-Y();%0A
+X(),
 %0A   
@@ -4127,181 +4127,65 @@
     
-final int x2 = x1 + rectangle.getWidth();%0A            final int y2 = y1 + rectangle.getHeight();%0A%0A            final int pointX = point.getX();%0A            final int pointY =
+                                                         
  poi
@@ -4193,17 +4193,17 @@
 t.getY()
-;
+,
 %0A       
@@ -4211,76 +4211,24 @@
     
-if (x1 %3C= pointX && pointX %3C= x2 && y1 %3C= pointY && pointY %3C= y2) %7B%0A
+                
     
@@ -4243,21 +4243,9 @@
     
-return true;%0A
+ 
     
@@ -4252,26 +4252,24 @@
         
-%7D%0A
         
 %7D%0A      
@@ -4264,30 +4264,23 @@
     
-%7D%0A
      
-   return false
+null) != 0
 ;%0A  

use pixman's build-in contains functionality