//=============================================================================
//
//  Copyright (c) Kitware, Inc.
//  All rights reserved.
//  See LICENSE.txt for details.
//
//  This software is distributed WITHOUT ANY WARRANTY; without even
//  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
//  PURPOSE.  See the above copyright notice for more information.
//
//=============================================================================
#include "smtk/common/RangeDetector.h"

#include "smtk/common/testing/cxx/helpers.h"

#include <iostream>
#include <sstream>

using namespace smtk::common;

template<typename T, typename U>
void checkRanges(T rd, U expected)
{
  std::map<int, int>::const_iterator rdit;
  int ei = 0;
  for (rdit = rd.ranges().begin(); rdit != rd.ranges().end(); ++rdit, ++ei)
  {
    std::ostringstream msg;
    msg << "Expected range " << ei << " to be " << expected[ei][0] << ", " << expected[ei][1]
        << " but it was " << rdit->first << ", " << rdit->second << " instead.";
    test(rdit->first == expected[ei][0] && rdit->second == expected[ei][1], msg.str());
  }
}

int main()
{
  RangeDetector<int> rd;

  test(rd.ranges().empty(), "Ranges not initially empty.");
  std::cout << "Initializing with {1, 2, 3, 5, 6, 7, 11}\n";
  rd.insert(1);
  rd.insert(2);
  rd.insert(3);
  rd.insert(5);
  rd.insert(6);
  rd.insert(7);
  rd.insert(11);
  rd.dump();
  test(rd.ranges().size() == 3, "Expected 3 ranges [1,3], [5,7], [11,11].");
  test(rd.size() == 7, "Expected 7 entries.");
  int expected1[3][2] = { { 1, 3 }, { 5, 7 }, { 11, 11 } };
  checkRanges(rd, expected1);

  std::cout << "Inserting 4\n";
  rd.insert(4);
  rd.dump();
  test(rd.ranges().size() == 2, "Expected 2 ranges [1,7], [11,11].");
  int expected2[2][2] = { { 1, 7 }, { 11, 11 } };
  checkRanges(rd, expected2);

  std::cout << "Inserting 10\n";
  rd.insert(10);
  rd.dump();
  test(rd.ranges().size() == 2, "Expected 2 ranges [1,7], [10,11].");
  int expected3[2][2] = { { 1, 7 }, { 10, 11 } };
  checkRanges(rd, expected3);

  std::cout << "Inserting 8\n";
  rd.insert(8);
  rd.dump();
  test(rd.ranges().size() == 2, "Expected 2 ranges [1,8], [10,11].");
  int expected4[2][2] = { { 1, 8 }, { 10, 11 } };
  checkRanges(rd, expected4);

  std::cout << "Inserting 9\n";
  rd.insert(9);
  rd.dump();
  test(rd.ranges().size() == 1, "Expected 1 range  [1,11].");
  int expected5[1][2] = { { 1, 11 } };
  checkRanges(rd, expected5);

  rd.clear();
  test(rd.ranges().empty(), "Could not reset range detector.");
  return 0;
}
