/*
 *  Copyright (c) 2010 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.
 */


#ifndef VP8_COMMON_FINDNEARMV_H_
#define VP8_COMMON_FINDNEARMV_H_

#include "mv.h"
#include "blockd.h"
#include "modecont.h"
#include "treecoder.h"

#ifdef __cplusplus
extern "C" {
#endif


static void mv_bias(int refmb_ref_frame_sign_bias, int refframe, int_mv *mvp,
                    const int *ref_frame_sign_bias)
{
    if (refmb_ref_frame_sign_bias != ref_frame_sign_bias[refframe])
    {
        mvp->as_mv.row *= -1;
        mvp->as_mv.col *= -1;
    }
}

#define LEFT_TOP_MARGIN (16 << 3)
#define RIGHT_BOTTOM_MARGIN (16 << 3)
static void vp8_clamp_mv2(int_mv *mv, const MACROBLOCKD *xd)
{
    if (mv->as_mv.col < (xd->mb_to_left_edge - LEFT_TOP_MARGIN))
        mv->as_mv.col = xd->mb_to_left_edge - LEFT_TOP_MARGIN;
    else if (mv->as_mv.col > xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN)
        mv->as_mv.col = xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN;

    if (mv->as_mv.row < (xd->mb_to_top_edge - LEFT_TOP_MARGIN))
        mv->as_mv.row = xd->mb_to_top_edge - LEFT_TOP_MARGIN;
    else if (mv->as_mv.row > xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN)
        mv->as_mv.row = xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN;
}

static void vp8_clamp_mv(int_mv *mv, int mb_to_left_edge, int mb_to_right_edge,
                         int mb_to_top_edge, int mb_to_bottom_edge)
{
    mv->as_mv.col = (mv->as_mv.col < mb_to_left_edge) ?
        mb_to_left_edge : mv->as_mv.col;
    mv->as_mv.col = (mv->as_mv.col > mb_to_right_edge) ?
        mb_to_right_edge : mv->as_mv.col;
    mv->as_mv.row = (mv->as_mv.row < mb_to_top_edge) ?
        mb_to_top_edge : mv->as_mv.row;
    mv->as_mv.row = (mv->as_mv.row > mb_to_bottom_edge) ?
        mb_to_bottom_edge : mv->as_mv.row;
}
static unsigned int vp8_check_mv_bounds(int_mv *mv, int mb_to_left_edge,
                                int mb_to_right_edge, int mb_to_top_edge,
                                int mb_to_bottom_edge)
{
    unsigned int need_to_clamp;
    need_to_clamp = (mv->as_mv.col < mb_to_left_edge);
    need_to_clamp |= (mv->as_mv.col > mb_to_right_edge);
    need_to_clamp |= (mv->as_mv.row < mb_to_top_edge);
    need_to_clamp |= (mv->as_mv.row > mb_to_bottom_edge);
    return need_to_clamp;
}

void vp8_find_near_mvs
(
    MACROBLOCKD *xd,
    const MODE_INFO *here,
    int_mv *nearest, int_mv *nearby, int_mv *best,
    int near_mv_ref_cts[4],
    int refframe,
    int *ref_frame_sign_bias
);


int vp8_find_near_mvs_bias
(
    MACROBLOCKD *xd,
    const MODE_INFO *here,
    int_mv mode_mv_sb[2][MB_MODE_COUNT],
    int_mv best_mv_sb[2],
    int cnt[4],
    int refframe,
    int *ref_frame_sign_bias
);


vp8_prob *vp8_mv_ref_probs(
    vp8_prob p[VP8_MVREFS-1], const int near_mv_ref_ct[4]
);

extern const unsigned char vp8_mbsplit_offset[4][16];


static int left_block_mv(const MODE_INFO *cur_mb, int b)
{
    if (!(b & 3))
    {
        /* On L edge, get from MB to left of us */
        --cur_mb;

        if(cur_mb->mbmi.mode != SPLITMV)
            return cur_mb->mbmi.mv.as_int;
        b += 4;
    }

    return (cur_mb->bmi + b - 1)->mv.as_int;
}

static int above_block_mv(const MODE_INFO *cur_mb, int b, int mi_stride)
{
    if (!(b >> 2))
    {
        /* On top edge, get from MB above us */
        cur_mb -= mi_stride;

        if(cur_mb->mbmi.mode != SPLITMV)
            return cur_mb->mbmi.mv.as_int;
        b += 16;
    }

    return (cur_mb->bmi + (b - 4))->mv.as_int;
}
static B_PREDICTION_MODE left_block_mode(const MODE_INFO *cur_mb, int b)
{
    if (!(b & 3))
    {
        /* On L edge, get from MB to left of us */
        --cur_mb;
        switch (cur_mb->mbmi.mode)
        {
            case B_PRED:
              return (cur_mb->bmi + b + 3)->as_mode;
            case DC_PRED:
                return B_DC_PRED;
            case V_PRED:
                return B_VE_PRED;
            case H_PRED:
                return B_HE_PRED;
            case TM_PRED:
                return B_TM_PRED;
            default:
                return B_DC_PRED;
        }
    }

    return (cur_mb->bmi + b - 1)->as_mode;
}

static B_PREDICTION_MODE above_block_mode(const MODE_INFO *cur_mb, int b, int mi_stride)
{
    if (!(b >> 2))
    {
        /* On top edge, get from MB above us */
        cur_mb -= mi_stride;

        switch (cur_mb->mbmi.mode)
        {
            case B_PRED:
              return (cur_mb->bmi + b + 12)->as_mode;
            case DC_PRED:
                return B_DC_PRED;
            case V_PRED:
                return B_VE_PRED;
            case H_PRED:
                return B_HE_PRED;
            case TM_PRED:
                return B_TM_PRED;
            default:
                return B_DC_PRED;
        }
    }

    return (cur_mb->bmi + b - 4)->as_mode;
}

#ifdef __cplusplus
}  // extern "C"
#endif

#endif  // VP8_COMMON_FINDNEARMV_H_
