// File: crn_arealist.h - 2D shape algebra
// See Copyright Notice and license at the end of inc/crnlib.h
#pragma once

namespace crnlib
{
   struct Area
   {
      struct Area *Pprev, *Pnext;

      int x1, y1, x2, y2;
      
      uint get_width() const { return x2 - x1 + 1; }
      uint get_height() const { return y2 - y1 + 1; }
      uint get_area() const { return get_width() * get_height(); }
   };

   typedef Area * Area_Ptr;

   struct Area_List
   {
      int total_areas;
      int next_free;

      Area *Phead, *Ptail, *Pfree;
   };

   typedef Area_List * Area_List_Ptr;

   Area_List * Area_List_init(int max_areas);
   void Area_List_deinit(Area_List* Pobj_base);

   void Area_List_print(Area_List *Plist);

   Area_List * Area_List_dup_new(Area_List *Plist,
                                 int x_ofs, int y_ofs);
                                 
   uint Area_List_get_num(Area_List* Plist);                                 

   // src and dst area lists must have the same number of total areas.
   void Area_List_dup(Area_List *Psrc_list,
                      Area_List *Pdst_list,
                      int x_ofs, int y_ofs);

   void Area_List_copy(Area_List *Psrc_list,
                       Area_List *Pdst_list,
                       int x_ofs, int y_ofs);

   void Area_List_clear(Area_List *Plist);

   void Area_List_set(Area_List *Plist,
                      int x1, int y1, int x2, int y2);

   // logical: x and (not y)
   void Area_List_remove(Area_List *Plist,
                         int x1, int y1, int x2, int y2);

   // logical: x or y
   void Area_List_insert(Area_List *Plist,
                         int x1, int y1, int x2, int y2,
                         bool combine); 

   // logical: x and y
   void Area_List_intersect_area(Area_List *Plist,
                                 int x1, int y1, int x2, int y2);

   // logical: x and y
   void Area_List_intersect_Area_List(Area_List *Pouter_list,
                                      Area_List *Pinner_list,
                                      Area_List *Pdst_list);

   Area_List_Ptr Area_List_create_optimal(Area_List_Ptr Plist);

} // namespace crnlib