#include <stdlib.h>
#include <stdio.h>

#define Uses_LineLengthArray
#include "ceditor.h"

/****************************************************************************

    Class for a transparent and dynamic array used for the length of the
  lines and for the syntax flags.

****************************************************************************/

const incBytes=4096;
const incWords=incBytes/2;
#define MaskGranul 0xFFFFF000L

LineLengthArray::LineLengthArray()
{
 elArray=(unsigned short*)malloc(incBytes);
 elArrayAttr=(unsigned short*)malloc(incBytes);
 if (elArray==NULL || elArrayAttr==NULL)
    MaxPos=0;
 else
    MaxPos=incWords;
 Length=0;
}

LineLengthArray::~LineLengthArray()
{
 if (elArray!=NULL)
    free(elArray);
 if (elArrayAttr!=NULL)
    free(elArrayAttr);
 elArrayAttr=elArray=NULL;
}

void LineLengthArray::set(unsigned pos, unsigned short val)
{
 if (pos<MaxPos)
   {
    elArray[pos]=val;
   }
 else
   {
    unsigned NewSize=(unsigned)(((pos<<1)+incBytes) & MaskGranul);

    if ((elArray=(unsigned short *)realloc(elArray,NewSize))==NULL
        || (elArrayAttr=(unsigned short *)realloc(elArrayAttr,NewSize))==NULL)
       abort();
    else
     {
      MaxPos=(NewSize>>1);
      elArray[pos]=val;
     }
   }
 if (++pos>Length)
    Length=pos;
 return;
}

void LineLengthArray::setAttr(unsigned pos, unsigned short attr)
{
 if (pos>=MaxPos)
    set(pos,0);
 elArrayAttr[pos]=attr;
 return;
}

void LineLengthArray::setAll(unsigned pos, unsigned short length,
			     unsigned short attr)
{
 set(pos,length);
 elArrayAttr[pos]=attr;
 return;
}

void LineLengthArray::insert(unsigned pos, unsigned short val)
{
 if (Length>=MaxPos)
   {
    unsigned NewSize=(MaxPos<<1)+incBytes;

    if ((elArray=(unsigned short *)realloc(elArray,NewSize))==NULL
        || (elArrayAttr=(unsigned short *)realloc(elArrayAttr,NewSize))==NULL)
      {
       printf("Aaahh! largo: %u tama¤o: %u\n",Length,NewSize);
       abort();
      }
    else
       MaxPos=(NewSize>>1);
   }
 memmove(&elArray[pos+1],&elArray[pos],(Length-pos)<<1);
 memmove(&elArrayAttr[pos+1],&elArrayAttr[pos],(Length-pos)<<1);
 Length++;
 elArray[pos]=val;
}

void LineLengthArray::del(unsigned pos)
{
 memcpy(&elArray[pos],&elArray[pos+1],(Length-pos-1)<<1);
 memcpy(&elArrayAttr[pos],&elArrayAttr[pos+1],(Length-pos-1)<<1);
 Length--;
}

void LineLengthArray::deleteRange(unsigned from,unsigned to)
{
 unsigned count=to-from+1;
 memcpy(&elArray[from],&elArray[to+1],(Length-from-count)<<1);
 memcpy(&elArrayAttr[from],&elArrayAttr[to+1],(Length-from-count)<<1);
 Length-=count;
}

