/*
 *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "vp8/common/onyxc_int.h"

#define MAX_REGIONS 24000
#ifndef NULL
#define NULL 0
#endif

#define min_mbs_in_region 3

// this linked list structure holds equivalences for connected
// component labeling
struct list_el {
   int label;
   int seg_value;
   int count;
   struct list_el * next;
};
typedef struct list_el item;

// connected colorsegments
typedef struct
{
  int min_x;
  int min_y;
  int max_x;
  int max_y;
  long long sum_x;
  long long sum_y;
  int pixels;
  int seg_value;
  int label;
} segment_info;


typedef enum
{
  SEGMENT_MODE,
  SEGMENT_MV,
  SEGMENT_REFFRAME,
  SEGMENT_SKIPPED
} SEGMENT_TYPE;


// this merges the two equivalence lists and
// then makes sure that every label points to the same
// equivalence list
void merge ( item *labels, int u, int v )
{
  item *a = labels[u].next;
  item *b = labels[v].next;
  item c;
  item *it = &c;
  int count;

  // check if they are already merged
  if(u==v || a==b)
    return;

  count = a->count + b->count;

  // merge 2 sorted linked lists.
  while ( a != NULL && b != NULL )
  {
    if ( a->label < b->label)
    {
      it->next = a;
      a = a->next;
    }
    else
    {
      it->next = b;
      b = b->next;
    }

    it = it->next;
  }

  if ( a == NULL )
    it->next = b;
  else
    it->next = a;

  it = c.next;

  // make sure every equivalence in the linked list points to this new ll
  while( it != NULL)
  {
    labels[it->label].next = c.next;
    it=it->next;
  }
  c.next->count = count;

}

void segment_via_mode_info( VP8_COMMON *oci, int how)
{
    MODE_INFO *mi = oci->mi;
    int i,j;
    int mb_index = 0;

    int label=1;
    int pitch = oci->mb_cols;

    // holds linked list equivalences
    // the max should probably be allocated at a higher level in oci
    item equivalences[MAX_REGIONS];
    int eq_ptr = 0;
    item labels[MAX_REGIONS];
    segment_info segments[MAX_REGIONS];
    int label_count = 1;
    int labeling[400*300];
    int *lp = labeling;

    label_count = 1;
    memset(labels,0,sizeof(labels));
    memset(segments,0,sizeof(segments));

    /* Go through each macroblock first pass labelling */
    for (i = 0; i < oci->mb_rows; i++,lp+=pitch)
    {
        for (j = 0; j < oci->mb_cols; j++)
        {
          // int above seg_value, left seg_value, this seg_value...
          int a=-1,l=-1,n=-1;

          // above label, left label
          int al=-1,ll=-1;
          if(i)
          {
            al=lp[j-pitch];
            a = labels[al].next->seg_value;
          }
          if(j)
          {
            ll=lp[j-1];
            l = labels[ll].next->seg_value;
          }

          // what setting are we going to do the implicit segmentation on
          switch (how)
          {
            case SEGMENT_MODE:
              n= mi[mb_index].mbmi.mode;
              break;
            case SEGMENT_MV:
              n = mi[mb_index].mbmi.mv.as_int;
              if(mi[mb_index].mbmi.ref_frame == INTRA_FRAME)
                 n=-9999999;
              break;
            case SEGMENT_REFFRAME:
              n = mi[mb_index].mbmi.ref_frame;
              break;
            case SEGMENT_SKIPPED:
              n = mi[mb_index].mbmi.mb_skip_coeff;
              break;
          }

          // above and left both have the same seg_value
          if(n==a&&n==l)
          {
            // pick the lowest label
            lp[j] = (al<ll?al:ll);
            labels[lp[j]].next->count++;

            // merge the above and left equivalencies
            merge( labels, al, ll );
          }
          // this matches above seg_value
          else if(n==a)
          {
              // give it the same label as above
              lp[j]=al;
              labels[al].next->count++;
          }
          // this matches left seg_value
          else if(n==l)
          {
              // give it the same label as above
              lp[j]=ll;
              labels[ll].next->count++;
          }
          else
          {
              // new label doesn't match either
              item *e = &labels[label];
              item *nl = &equivalences[eq_ptr++];
              lp[j]=label;
              nl->label = label;
              nl->next = 0;
              nl->seg_value = n;
              nl->count = 1;
              e->next = nl;
              label++;
          }
          mb_index++;
      }
      mb_index++;
    }
    lp = labeling;

    // give new labels to regions
    for(i=1;i<label;i++)
      if(labels[i].next->count >min_mbs_in_region  &&  labels[labels[i].next->label].label == 0 )
      {
        segment_info *cs= &segments[label_count];
        cs->label = label_count;
        labels[labels[i].next->label].label = label_count++;
        labels[labels[i].next->label].seg_value  = labels[i].next->seg_value;
        cs->seg_value = labels[labels[i].next->label].seg_value;
        cs->min_x = oci->mb_cols;
        cs->min_y = oci->mb_rows;
        cs->max_x = 0;
        cs->max_y = 0;
        cs->sum_x = 0;
        cs->sum_y = 0;
        cs->pixels= 0;

      }
    lp = labeling;

    // this is just to gather stats...
    for(i=0;i<oci->mb_rows;i++,lp+=pitch)
    {
      for(j=0;j<oci->mb_cols;j++)
      {
         segment_info *cs;
         int oldlab = labels[lp[j]].next->label;
         int lab = labels[oldlab].label;
         lp[j] = lab;

         cs= &segments[lab];

         cs->min_x = (j<cs->min_x?j:cs->min_x);
         cs->max_x = (j>cs->max_x?j:cs->max_x);
         cs->min_y = (i<cs->min_y?i:cs->min_y);
         cs->max_y = (i>cs->max_y?i:cs->max_y);
         cs->sum_x += j;
         cs->sum_y += i;
         cs->pixels ++;

         lp[j] = lab;
         mb_index++;
      }
      mb_index++;
    }

    {
      lp = labeling;
      printf("labelling \n");
      mb_index = 0;
      for(i=0;i<oci->mb_rows;i++,lp+=pitch)
      {
        for(j=0;j<oci->mb_cols;j++)
        {
          printf("%4d",lp[j]);
        }
        printf("            ");
        for(j=0;j<oci->mb_cols;j++,mb_index++)
        {
          //printf("%3d",mi[mb_index].mbmi.mode );
          printf("%4d:%4d",mi[mb_index].mbmi.mv.as_mv.row,mi[mb_index].mbmi.mv.as_mv.col );
        }
        printf("\n");
        ++mb_index;
      }
      printf("\n");
    }
}

