/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.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.
 */

#ifndef ANDROID_UI_PRIVATE_REGION_HELPER_H
#define ANDROID_UI_PRIVATE_REGION_HELPER_H

#include <stdint.h>
#include <sys/types.h>

namespace android {
// ----------------------------------------------------------------------------

template<typename RECT>
class region_operator
{
public:
    typedef typename RECT::value_type TYPE;    
    static const TYPE max_value = 0x7FFFFFF;

    /* 
     * Common boolean operations:
     * value is computed as 0b101 op 0b110
     *    other boolean operation are possible, simply compute
     *    their corresponding value with the above formulae and use
     *    it when instantiating a region_operator.
     */
    static const uint32_t LHS = 0x5;  // 0b101
    static const uint32_t RHS = 0x6;  // 0b110
    enum {
        op_nand = LHS & ~RHS,
        op_and  = LHS &  RHS,
        op_or   = LHS |  RHS,
        op_xor  = LHS ^  RHS
    };

    struct region {
        RECT const* rects;
        size_t count;
        TYPE dx;
        TYPE dy;
        inline region(const region& rhs) 
            : rects(rhs.rects), count(rhs.count), dx(rhs.dx), dy(rhs.dy) { }
        inline region(RECT const* r, size_t c) 
            : rects(r), count(c), dx(), dy() { }
        inline region(RECT const* r, size_t c, TYPE dx, TYPE dy) 
            : rects(r), count(c), dx(dx), dy(dy) { }
    };

    class region_rasterizer {
        friend class region_operator;
        virtual void operator()(const RECT& rect) = 0;
    public:
        virtual ~region_rasterizer() { };
    };
    
    inline region_operator(int op, const region& lhs, const region& rhs) 
        : op_mask(op), spanner(lhs, rhs) 
    {
    }

    void operator()(region_rasterizer& rasterizer) {
        RECT current;
        do {
            SpannerInner spannerInner(spanner.lhs, spanner.rhs);
            int inside = spanner.next(current.top, current.bottom);
            spannerInner.prepare(inside);
            do {
                TYPE left, right;
                int inside = spannerInner.next(current.left, current.right);
                if ((op_mask >> inside) & 1) {
                    if (current.left < current.right && 
                            current.top < current.bottom) {
                        rasterizer(current);
                    }
                }
            } while(!spannerInner.isDone());
        } while(!spanner.isDone());
    }

private:    
    uint32_t op_mask;

    class SpannerBase
    {
    public:
        SpannerBase()
            : lhs_head(max_value), lhs_tail(max_value),
              rhs_head(max_value), rhs_tail(max_value) {
        }

        enum {
            lhs_before_rhs   = 0,
            lhs_after_rhs    = 1,
            lhs_coincide_rhs = 2
        };

    protected:
        TYPE lhs_head;
        TYPE lhs_tail;
        TYPE rhs_head;
        TYPE rhs_tail;

        inline int next(TYPE& head, TYPE& tail,
                bool& more_lhs, bool& more_rhs) 
        {
            int inside;
            more_lhs = false;
            more_rhs = false;
            if (lhs_head < rhs_head) {
                inside = lhs_before_rhs;
                head = lhs_head;
                if (lhs_tail <= rhs_head) {
                    tail = lhs_tail;
                    more_lhs = true;
                } else {
                    lhs_head = rhs_head;
                    tail = rhs_head;
                }
            } else if (rhs_head < lhs_head) {
                inside = lhs_after_rhs;
                head = rhs_head;
                if (rhs_tail <= lhs_head) {
                    tail = rhs_tail;
                    more_rhs = true;
                } else {
                    rhs_head = lhs_head;
                    tail = lhs_head;
                }
            } else {
                inside = lhs_coincide_rhs;
                head = lhs_head;
                if (lhs_tail <= rhs_tail) {
                    tail = rhs_head = lhs_tail;
                    more_lhs = true;
                }
                if (rhs_tail <= lhs_tail) {
                    tail = lhs_head = rhs_tail;
                    more_rhs = true;
                }
            }
            return inside;
        }
    };

    class Spanner : protected SpannerBase 
    {
        friend class region_operator;
        region lhs;
        region rhs;

    public:
        inline Spanner(const region& lhs, const region& rhs)
        : lhs(lhs), rhs(rhs)
        {
            if (lhs.count) {
                SpannerBase::lhs_head = lhs.rects->top      + lhs.dy;
                SpannerBase::lhs_tail = lhs.rects->bottom   + lhs.dy;
            }
            if (rhs.count) {
                SpannerBase::rhs_head = rhs.rects->top      + rhs.dy;
                SpannerBase::rhs_tail = rhs.rects->bottom   + rhs.dy;
            }
        }

        inline bool isDone() const {
            return !rhs.count && !lhs.count;
        }

        inline int next(TYPE& top, TYPE& bottom) 
        {
            bool more_lhs = false;
            bool more_rhs = false;
            int inside = SpannerBase::next(top, bottom, more_lhs, more_rhs);
            if (more_lhs) {
                advance(lhs, SpannerBase::lhs_head, SpannerBase::lhs_tail);
            }
            if (more_rhs) {
                advance(rhs, SpannerBase::rhs_head, SpannerBase::rhs_tail);
            }
            return inside;
        }

    private:
        static inline 
        void advance(region& reg, TYPE& aTop, TYPE& aBottom) {
            // got to next span
            size_t count = reg.count;
            RECT const * rects = reg.rects;
            RECT const * const end = rects + count;
            const int top = rects->top;
            while (rects != end && rects->top == top) {
                rects++;
                count--;
            }
            if (rects != end) {
                aTop    = rects->top    + reg.dy;
                aBottom = rects->bottom + reg.dy;
            } else {
                aTop    = max_value;
                aBottom = max_value;
            }
            reg.rects = rects;
            reg.count = count;
        }
    };

    class SpannerInner : protected SpannerBase 
    {
        region lhs;
        region rhs;
        
    public:
        inline SpannerInner(const region& lhs, const region& rhs)
            : lhs(lhs), rhs(rhs) 
        {
        }

        inline void prepare(int inside) {
            if (inside == SpannerBase::lhs_before_rhs) {
                if (lhs.count) {
                    SpannerBase::lhs_head = lhs.rects->left  + lhs.dx;
                    SpannerBase::lhs_tail = lhs.rects->right + lhs.dx;
                }
                SpannerBase::rhs_head = max_value;
                SpannerBase::rhs_tail = max_value;
            } else if (inside == SpannerBase::lhs_after_rhs) {
                SpannerBase::lhs_head = max_value;
                SpannerBase::lhs_tail = max_value;
                if (rhs.count) {
                    SpannerBase::rhs_head = rhs.rects->left  + rhs.dx;
                    SpannerBase::rhs_tail = rhs.rects->right + rhs.dx;
                }
            } else {
                if (lhs.count) {
                    SpannerBase::lhs_head = lhs.rects->left  + lhs.dx;
                    SpannerBase::lhs_tail = lhs.rects->right + lhs.dx;
                }
                if (rhs.count) {
                    SpannerBase::rhs_head = rhs.rects->left  + rhs.dx;
                    SpannerBase::rhs_tail = rhs.rects->right + rhs.dx;
                }
            }
        }

        inline bool isDone() const {
            return SpannerBase::lhs_head == max_value && 
                   SpannerBase::rhs_head == max_value;
        }

        inline int next(TYPE& left, TYPE& right) 
        {
            bool more_lhs = false;
            bool more_rhs = false;
            int inside = SpannerBase::next(left, right, more_lhs, more_rhs);
            if (more_lhs) {
                advance(lhs, SpannerBase::lhs_head, SpannerBase::lhs_tail);
            }
            if (more_rhs) {
                advance(rhs, SpannerBase::rhs_head, SpannerBase::rhs_tail);
            }
            return inside;
        }

    private:
        static inline 
        void advance(region& reg, TYPE& left, TYPE& right) {
            if (reg.rects && reg.count) {
                const int cur_span_top = reg.rects->top;
                reg.rects++;
                reg.count--;
                if (!reg.count || reg.rects->top != cur_span_top) {
                    left  = max_value;
                    right = max_value;
                } else {
                    left  = reg.rects->left  + reg.dx;
                    right = reg.rects->right + reg.dx;
                }
            }
        }
    };

    Spanner spanner;
};

// ----------------------------------------------------------------------------
};

#endif /* ANDROID_UI_PRIVATE_REGION_HELPER_H */
