/*
 *  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
#define NULL 0

#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");
    }
}

