#include "FileIterator.h"

#undef Debug
#define Debug if(0)

using namespace std;

/**
 *
 * This object contains information that's necessary for proper implementation
 * of seek and a few other nice features. To create it, we need to read the
 * whole media first. That's why we won't do it for non-local media.
 */

framepos_t ASFStreamSeekInfo::prevKeyFrame(framepos_t kf) const
{
    if (kf == ERR || kf >= size())
	return ERR;

    for (unsigned int i = kf - 1; i > 0; i--)
	if (operator[](i).keyframe)
	    return i;

    return 0;
}

framepos_t ASFStreamSeekInfo::nextKeyFrame(framepos_t kf) const
{
    if (kf == ERR || kf >= size())
	return ERR;

    for (unsigned int i = kf + 1; i < size(); i++)
	if (operator[](i).keyframe)
	    return i;

    return ERR;
}

framepos_t ASFStreamSeekInfo::nearestKeyFrame(framepos_t kf) const
{
    if (kf >= size())
	return ERR;

    framepos_t prev_kf = prevKeyFrame(kf);
    framepos_t next_kf = nextKeyFrame(kf);

    return (kf - prev_kf < next_kf - kf) ? prev_kf : next_kf;
}

framepos_t ASFStreamSeekInfo::find(unsigned int sktime) const
{
    if (!size() || sktime == ERR)
	return ERR;

    framepos_t h = size() - 1;
    framepos_t l = (sktime < operator[](h).object_start_time) ? 0 : h;

    while (l < h)
    {
	framepos_t m = (l + h) / 2;
	if (sktime < operator[](m).object_start_time)
	    h = m;
	else if (sktime >= operator[](m + 1).object_start_time)
	    l = m + 1;
	else
	{
	    l = m;
	    break;
	}
    }

    //cout << "TIME find " << sktime << "  cur  " << operator[](l).object_start_time
    //    << "  nex  " << operator[](l + 1).object_start_time
    //   << "   -> " << l << endl;
    return l;
}
