/**********************************************************************
 * File:						coutln.c      (Formerly:  coutline.c)
 * Description: Code for the C_OUTLINE class.
 * Author:					Ray Smith
 * Created:					Mon Oct 07 16:01:57 BST 1991
 *
 * (C) Copyright 1991, Hewlett-Packard Ltd.
 ** 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           COUTLN_H
#define           COUTLN_H

#include          "crakedge.h"
#include          "mod128.h"
#include          "bits16.h"
#include          "rect.h"
#include          "blckerr.h"
#ifndef GRAPHICS_DISABLED
#include          "scrollview.h"
#endif

#define INTERSECTING    MAX_INT16//no winding number

                                 //mask to get step
#define STEP_MASK       3

enum C_OUTLINE_FLAGS
{
  COUT_INVERSE                   //White on black blob
};

class DLLSYM C_OUTLINE;          //forward declaration

ELISTIZEH_S (C_OUTLINE)
class DLLSYM C_OUTLINE:public ELIST_LINK
{
  public:
    C_OUTLINE() {  //empty constructor
      steps = NULL;
    }
    C_OUTLINE(                     //constructor
              CRACKEDGE *startpt,  //from edge detector
              ICOORD bot_left,     //bounding box //length of loop
              ICOORD top_right,
              inT16 length);
    C_OUTLINE(ICOORD startpt,    //start of loop
              DIR128 *new_steps,  //steps in loop
              inT16 length);     //length of loop
                                 //outline to copy
    C_OUTLINE(C_OUTLINE *srcline, FCOORD rotation);  //and rotate
    ~C_OUTLINE () {              //destructor
      if (steps != NULL)
        free_mem(steps);
      steps = NULL;
    }

    BOOL8 flag(                               //test flag
               C_OUTLINE_FLAGS mask) const {  //flag to test
      return flags.bit (mask);
    }
    void set_flag(                       //set flag value
                  C_OUTLINE_FLAGS mask,  //flag to test
                  BOOL8 value) {         //value to set
      flags.set_bit (mask, value);
    }

    C_OUTLINE_LIST *child() {  //get child list
      return &children;
    }

                                 //access function
    const TBOX &bounding_box() const {
      return box;
    }
    void set_step(                    //set a step
                  inT16 stepindex,    //index of step
                  inT8 stepdir) {     //chain code
      int shift = stepindex%4 * 2;
      uinT8 mask = 3 << shift;
      steps[stepindex/4] = ((stepdir << shift) & mask) |
                           (steps[stepindex/4] & ~mask);
      //squeeze 4 into byte
    }
    void set_step(                    //set a step
                  inT16 stepindex,    //index of step
                  DIR128 stepdir) {   //direction
                                 //clean it
      inT8 chaindir = stepdir.get_dir() >> (DIRBITS - 2);
                                 //difference
      set_step(stepindex, chaindir);
      //squeeze 4 into byte
    }

                                 //get start position
    const ICOORD &start_pos() const {
      return start;
    }
    inT32 pathlength() const {  //get path length
      return stepcount;
    }
    // Return step at a given index as a DIR128.
    DIR128 step_dir(inT16 index) const {
      return DIR128((inT16)(((steps[index/4] >> (index%4 * 2)) & STEP_MASK) <<
                      (DIRBITS - 2)));
    }
    // Return the step vector for the given outline position.
    ICOORD step(inT16 index) const { //index of step
      return step_coords[(steps[index/4] >> (index%4 * 2)) & STEP_MASK];
    }

    inT32 area();  //return area
    inT32 outer_area();  //return area
    inT32 count_transitions(                   //count maxima
                            inT32 threshold);  //size threshold

    BOOL8 operator< (            //containment test
      const C_OUTLINE & other) const;
    BOOL8 operator> (            //containment test
      C_OUTLINE & other) const
    {
      return other < *this;      //use the < to do it
    }
    inT16 winding_number(                       //get winding number
                         ICOORD testpt) const;  //around this point
                                 //get direction
    inT16 turn_direction() const;
    void reverse();  //reverse direction

    void move(                    // reposition outline
              const ICOORD vec);  // by vector

#ifndef GRAPHICS_DISABLED
    void plot(                       //draw one
              ScrollView* window,         //window to draw in
              ScrollView::Color colour) const;  //colour to draw it
#endif

    void prep_serialise() {  //set ptrs to counts
      children.prep_serialise ();
    }

    void dump(  //write external bits
              FILE *f) {
                                 //stepcount = # bytes
      serialise_bytes (f, (void *) steps, step_mem());
      children.dump (f);
    }

    void de_dump(  //read external bits
                 FILE *f) {
      steps = (uinT8 *) de_serialise_bytes (f, step_mem());
      children.de_dump (f);
    }

                                 //assignment
    make_serialise (C_OUTLINE) C_OUTLINE & operator= (
      const C_OUTLINE & source); //from this

  private:
    int step_mem() const { return (stepcount+3) / 4; }

    TBOX box;                     //boudning box
    ICOORD start;                //start coord
    uinT8 *steps;                //step array
    inT16 stepcount;             //no of steps
    BITS16 flags;                //flags about outline
    C_OUTLINE_LIST children;     //child elements
    static ICOORD step_coords[4];
};
#endif
