#ifdef PC_SIM
#include <mem.h>
#endif
#ifdef TARGET_PC
#include <mem.h>
#endif
#include <math.h>
#include "cpb_module.h"
#include "DentedExtract.h"
//---------------------------------------------------------------------------
void ExtractDentedArea(int cameraIndex)
{
	int startX, startY, endX, endY;
	int x, y, i, j, m;
	int tempAddress, tempAddress2;
	int left;
	int right;
	int up;
	int down;
	int upleft;
	int upright;
	int downleft;
	int downright;

	int length;
	int maxHeight;
	int tempNeighborHeight[4];
	int n, l;
	int lengthTable[10];
	int startL, endL;
	int tempCount;
	int tempDentedDepth;
	int upValue;
	int downValue;
	int leftValue;
	int rightValue;
	int upleftValue;
	int downrightValue;
	int uprightValue;
	int downleftValue;
	int tempDiff;
	int addStepX, addStepY;
	int selfValue;
	int tempX, tempY;
	int maskSize;
  int topSW, bottomSW, leftSW, rightSW, topLeftSW, topRightSW, bottomLeftSW, bottomRightSW;
  int searchRange, r;
  int depthSW;
  unsigned char *expectedDentedArea;

	startX = tabletAreaInfo[AREA_INFO_ST_X_ADDRESS];
	endX = tabletAreaInfo[AREA_INFO_END_X_ADDRESS];
	startY = tabletAreaInfo[AREA_INFO_ST_Y_ADDRESS];
	endY = tabletAreaInfo[AREA_INFO_END_Y_ADDRESS];

  expectedDentedArea = GradientImage;

  memset(TempImage, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
  memset(noneGradientArea, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
  memcpy(ShapeBinaryImage, RotationThreeDImage, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);

  if ((TabletCharacter.length < 7000 / 37) && TabletCharacter.shape == ROUND)
  {
    maskSize = 3;
  }
  else
  {
    maskSize = 7;
    if(TabletCharacter.tabletDivisionLineInfo != NONE_DIVISION_LINE)
    {
      maskSize = 4;
    }
  }

  for (m = 0; m < EdgeLineCountForThreeDImage; m++)
  {
    tempX = EdgeLineForThreeDImage[m][0];
    tempY = EdgeLineForThreeDImage[m][1];
    for (i = tempY - maskSize; i <= tempY + maskSize; i++)
    {
      for (j = tempX - maskSize; j <= tempX + maskSize; j++)
      {
        if (j > 1 && j < MAX_IMAGE_WIDTH - 1 && i > 1 && i < MAX_IMAGE_HEIGHT - 1)
        {
          ShapeBinaryImage[MAX_IMAGE_WIDTH * i + j] = 0;
        }
      }
    }
  }

  maskSize = 10;
  for (m = 0; m < EdgeLineCountForThreeDImage; m++)
  {
    tempX = EdgeLineForThreeDImage[m][0];
    tempY = EdgeLineForThreeDImage[m][1];
    for (i = tempY - maskSize; i <= tempY + maskSize; i++)
    {
      for (j = tempX - maskSize; j <= tempX + maskSize; j++)
      {
        if (j > 1 && j < MAX_IMAGE_WIDTH - 1 && i > 1 && i < MAX_IMAGE_HEIGHT - 1)
        {
          if(RotationThreeDImage[MAX_IMAGE_WIDTH * i + j])
          {
            noneGradientArea[MAX_IMAGE_WIDTH * i + j] = 1;
          }
        }
      }
    }
  }

  if ((TabletCharacter.length < 7000 / 37) && TabletCharacter.shape == ROUND)
  {
    searchRange = 16;
    memset(expectedDentedArea, 0, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
    for (y = startY; y < endY; y++)
    {
      for (x = startX; x < endX; x++)
      {
        tempAddress = MAX_IMAGE_WIDTH * y + x;

        topSW = bottomSW = leftSW = rightSW = topLeftSW = topRightSW = bottomLeftSW = bottomRightSW = 0;
        depthSW = 0;
        if(RotationThreeDImage[tempAddress])
        {
          selfValue = RotationThreeDImage[tempAddress];

          for(r = searchRange; r >= 4; r-=4)
          {
            tempAddress2 = MAX_IMAGE_WIDTH * (y - r) + (x);
            if(RotationThreeDImage[tempAddress2])
            {
              tempDiff = RotationThreeDImage[tempAddress2] - selfValue;

              if(tempDiff > 0)
              {
                topSW = 1;
                break;
              }
            }
          }

          if(topSW)
          {
            for(r = searchRange; r >= 4; r-=4)
            {
              tempAddress2 = MAX_IMAGE_WIDTH * (y + r) + (x);
              if(RotationThreeDImage[tempAddress2])
              {
                tempDiff = RotationThreeDImage[tempAddress2] - selfValue;

                if(tempDiff > 0)
                {
                  bottomSW = 1;
                  break;
                }
              }
            }

            if(bottomSW)
            {
              depthSW = 1; 
            }
          }

          if(!depthSW)
          {
            for(r = searchRange; r >= 4; r-=4)
            {
              tempAddress2 = MAX_IMAGE_WIDTH * (y) + (x - r);
              if(RotationThreeDImage[tempAddress2])
              {
                tempDiff = RotationThreeDImage[tempAddress2] - selfValue;

                if(tempDiff > 0)
                {
                  leftSW = 1;
                  break;
                }
              }
            }

            if(leftSW)
            {
              for(r = searchRange; r >= 4; r-=4)
              {
                tempAddress2 = MAX_IMAGE_WIDTH * (y) + (x + r);
                if(RotationThreeDImage[tempAddress2])
                {
                  tempDiff = RotationThreeDImage[tempAddress2] - selfValue;

                  if(tempDiff > 0)
                  {
                    rightSW = 1;
                    break;
                  }
                }
              }

              if(rightSW)
              { 
                depthSW = 1;
              }
            }
          }

          if(!depthSW)
          {
            for(r = searchRange; r >= 4; r-=4)
            {
              tempAddress2 = MAX_IMAGE_WIDTH * (y - r) + (x - r);
              if(RotationThreeDImage[tempAddress2])
              {
                tempDiff = RotationThreeDImage[tempAddress2] - selfValue;

                if(tempDiff > 0)
                {
                  topLeftSW = 1;
                  break;
                }
              }
            }

            if(topLeftSW)
            {
              for(r = searchRange; r >= 4; r-=4)
              {
                tempAddress2 = MAX_IMAGE_WIDTH * (y + r) + (x + r);
                if(RotationThreeDImage[tempAddress2])
                {
                  tempDiff = RotationThreeDImage[tempAddress2] - selfValue;

                  if(tempDiff > 0)
                  {
                    bottomRightSW = 1;
                    break;
                  }
                }
              }

              if(bottomRightSW)
              {
                depthSW = 1;
              }
            }
          }

          if(!depthSW)
          {
            for(r = searchRange; r >= 4; r-=4)
            {
              tempAddress2 = MAX_IMAGE_WIDTH * (y - r) + (x + r);
              if(RotationThreeDImage[tempAddress2])
              {
                tempDiff = RotationThreeDImage[tempAddress2] - selfValue;

                if(tempDiff > 0)
                {
                  topRightSW = 1;
                  break;
                }
              }
            }

            if(topRightSW)
            {
              for(r = searchRange; r >= 4; r-=4)
              {
                tempAddress2 = MAX_IMAGE_WIDTH * (y + r) + (x - r);
                if(RotationThreeDImage[tempAddress2])
                {
                  tempDiff = RotationThreeDImage[tempAddress2] - selfValue;

                  if(tempDiff > 0)
                  {
                    bottomLeftSW = 1;
                    break;
                  }
                }
              }

              if(bottomLeftSW)
              {
                depthSW = 1;
              }
            }
          }

          if(depthSW)
          {
            expectedDentedArea[tempAddress] = 1;
          }
        }
      }
    }
  }
  else
  {
    memcpy(expectedDentedArea, RotationThreeDImage, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT);
  }

	if ((TabletCharacter.shape == ROUND || TabletCharacter.shape == ETC) && TabletCharacter.kind != SUGARCOATING)
	{
    if (TabletCharacter.length < 9000 / 37)
		{ // 9mm이하인 정제에 대해
			lengthTable[0] = 6 * TabletCharacter.length / (9000 / 37);
			lengthTable[1] = 13 * TabletCharacter.length / (9000 / 37);
			lengthTable[2] = 20 * TabletCharacter.length / (9000 / 37);
			lengthTable[3] = 30 * TabletCharacter.length / (9000 / 37);
			lengthTable[4] = 45 * TabletCharacter.length / (9000 / 37);
			lengthTable[5] = 45 * TabletCharacter.length / (9000 / 37);
			lengthTable[6] = 60 * TabletCharacter.length / (9000 / 37);
		}
		else
		{
			lengthTable[0] = 6;
			lengthTable[1] = 13;
			lengthTable[2] = 20;
			lengthTable[3] = 30;
			lengthTable[4] = 45;
			lengthTable[5] = 45;
			lengthTable[6] = 60;
		}
	}
	else
	{
		lengthTable[0] = 6;
		lengthTable[1] = 13;
		lengthTable[2] = 20;
		lengthTable[3] = 30;
		lengthTable[4] = 45;
		lengthTable[5] = 45;
		lengthTable[6] = 60;
	}

  if ((TabletCharacter.length < 7000 / 37) && TabletCharacter.shape == ROUND)
  {
    startL = 0;
	  endL = 3;
  }
  else
  {
    startL = 1;
	  endL = 4;
  }

  addStepX = 1;
  addStepY = 1;
    
	for (l = startL; l < endL; l++)
	{
		length = lengthTable[l];
		up = -MAX_IMAGE_WIDTH * length;
		down = MAX_IMAGE_WIDTH * length;
		left = -1 * length;
		right = 1 * length;
		upleft = (-MAX_IMAGE_WIDTH - 1)*length;
		upright = (-MAX_IMAGE_WIDTH + 1)*length;
		downleft = (MAX_IMAGE_WIDTH - 1)*length;
		downright = (MAX_IMAGE_WIDTH + 1)*length;

		for (y = startY; y < endY; y += addStepY)
		{
			for (x = startX; x < endX; x += addStepX)
			{
				tempAddress = MAX_IMAGE_WIDTH * y + x;

				if (ShapeBinaryImage[tempAddress] && expectedDentedArea[tempAddress])
				{
          maxHeight = 0;
          for (n = 0; n < 4; n++)
          {
            tempNeighborHeight[n] = 0;
          }

          tempAddress2 = tempAddress + up;
          if (tempAddress2 > MAX_IMAGE_WIDTH * 4 + 4 && tempAddress2 < MAX_IMAGE_WIDTH * (MAX_IMAGE_HEIGHT - 4) + MAX_IMAGE_WIDTH - 4)
            upValue = ShapeBinaryImage[tempAddress + up];
          else
            upValue = 0;

          tempAddress2 = tempAddress + down;
          if (tempAddress2 > MAX_IMAGE_WIDTH * 4 + 4 && tempAddress2 < MAX_IMAGE_WIDTH * (MAX_IMAGE_HEIGHT - 4) + MAX_IMAGE_WIDTH - 4)
            downValue = ShapeBinaryImage[tempAddress + down];
          else
            downValue = 0;

          tempAddress2 = tempAddress + left;
          if (tempAddress2 > MAX_IMAGE_WIDTH * 4 + 4 && tempAddress2 < MAX_IMAGE_WIDTH * (MAX_IMAGE_HEIGHT - 4) + MAX_IMAGE_WIDTH - 4)
            leftValue = ShapeBinaryImage[tempAddress + left];
          else
            leftValue = 0;

          tempAddress2 = tempAddress + right;
          if (tempAddress2 > MAX_IMAGE_WIDTH * 4 + 4 && tempAddress2 < MAX_IMAGE_WIDTH * (MAX_IMAGE_HEIGHT - 4) + MAX_IMAGE_WIDTH - 4)
            rightValue = ShapeBinaryImage[tempAddress + right];
          else
            rightValue = 0;

          tempAddress2 = tempAddress + upleft;
          if (tempAddress2 > MAX_IMAGE_WIDTH * 4 + 4 && tempAddress2 < MAX_IMAGE_WIDTH * (MAX_IMAGE_HEIGHT - 4) + MAX_IMAGE_WIDTH - 4)
            upleftValue = ShapeBinaryImage[tempAddress + upleft];
          else
            upleftValue = 0;

          tempAddress2 = tempAddress + downright;
          if (tempAddress2 > MAX_IMAGE_WIDTH * 4 + 4 && tempAddress2 < MAX_IMAGE_WIDTH * (MAX_IMAGE_HEIGHT - 4) + MAX_IMAGE_WIDTH - 4)
            downrightValue = ShapeBinaryImage[tempAddress + downright];
          else
            downrightValue = 0;

          tempAddress2 = tempAddress + upright;
          if (tempAddress2 > MAX_IMAGE_WIDTH * 4 + 4 && tempAddress2 < MAX_IMAGE_WIDTH * (MAX_IMAGE_HEIGHT - 4) + MAX_IMAGE_WIDTH - 4)
            uprightValue = ShapeBinaryImage[tempAddress + upright];
          else
            uprightValue = 0;

          tempAddress2 = tempAddress + downleft;
          if (tempAddress2 > MAX_IMAGE_WIDTH * 4 + 4 && tempAddress2 < MAX_IMAGE_WIDTH * (MAX_IMAGE_HEIGHT - 4) + MAX_IMAGE_WIDTH - 4)
            downleftValue = ShapeBinaryImage[tempAddress + downleft];
          else
            downleftValue = 0;

          if (upValue && downValue)
          {
            tempNeighborHeight[0] = upValue + downValue;
          }
          if (leftValue && rightValue)
          {
            tempNeighborHeight[1] = leftValue + rightValue;
          }
          if (upleftValue && downrightValue)
          {
            tempNeighborHeight[2] = upleftValue + downrightValue;
          }
          if (uprightValue && downleftValue)
          {
            tempNeighborHeight[3] = uprightValue + downleftValue;
          }
          for (n = 0; n < 4; n++)
          {
            if (tempNeighborHeight[n] / 2 > maxHeight)
            {
              maxHeight = tempNeighborHeight[n] / 2;
            }
          }
          if (maxHeight)
          {
            tempDiff = maxHeight - ShapeBinaryImage[tempAddress];

            if (tempDiff > 0)
            {
              if (tempDiff > TempImage[tempAddress])
              {
                TempImage[tempAddress] = tempDiff;
                DentedArea[tempAddress] = tempDiff;
              }
            }
          }
				}
			}
		}
	}

	//채우기
  for (y = startY; y < endY; y++)
  {
    for (x = startX; x < endX; x++)
    {
      tempAddress = MAX_IMAGE_WIDTH * y + x;

      if (TempImage[tempAddress] == 0)
      {
        tempCount = 0;
        tempDentedDepth = 0;

        // 3x3... for루프 풀어놓자
        for (i = y - 1; i <= y + 1; i++)
        {
          for (j = x - 1; j <= x + 1; j++)
          {
            if (j > 2 && j < MAX_IMAGE_WIDTH - 2 && i > 2 && i < MAX_IMAGE_HEIGHT - 2)
            {
              selfValue = TempImage[MAX_IMAGE_WIDTH * i + j];

              if(selfValue)
              {
                tempCount++;
                tempDentedDepth += selfValue;
              }
            }
          }
        }
        if (tempCount >= 4)
        {
          DentedArea[tempAddress] = tempDentedDepth / tempCount;
        }
      }
    }
	}
}
//---------------------------------------------------------------------------------------------------


