text: #include "pch.h"
  #include "tdd_surface_instance.h"
  using namespace std;
  
  namespace TDD
  {
  
  void SurfaceInstance::SelectAllChars()
  {
      MergeSelectCache(); //apply current select result
      not_selected_chars.clear();
      selected_chars = chars;
  }
  
  void SurfaceInstance::SelectChar(const Location & loc)
  {
      selected_chars.clear();
      AppendSelectChar(loc);
  }
  
  void SurfaceInstance::SelectChars(const Rect & rc)
  {
      selected_chars.clear();
      AppendSelectChars(rc);
  }
  
  void SurfaceInstance::AppendSelectChar(const Location & loc)
  {
      if (chars.count(loc))
      {
          selected_chars[loc] = chars[loc];
      }
      MakeSelectCache();
  }
  
  void SurfaceInstance::AppendSelectChars(const Rect & rc)
  {
      for (auto& it : chars)
      {
          if (rc.HitTest(it.first))
          {
              selected_chars[it.first] = it.second;
          }
      }
      MakeSelectCache();
  }
  
  void SurfaceInstance::MakeSelectCache()
  {
      not_selected_chars = chars;
  
      decltype(selected_chars) selected_chars_fixed;
      for (auto& it : selected_chars)
      {
          selected_chars_fixed[it.first] = it.second;
  
          auto c = it.second.GetCharacter({ 0, 0 });
          if (c && (*c)[0] == wide_character_filler)
          {
              //find left
              auto lloc = it.first - Location{1, 0};
              while (chars.count(lloc))
              {
                  auto& lsf = chars.at(lloc);
                  selected_chars_fixed[lloc] = lsf;
                  auto lc = lsf.GetCharacter({ 0, 0 });
                  if (lc && (*lc)[0] == wide_character_filler)
                  {
                      lloc = lloc - Location{ 1, 0 };
                      continue;
                  }
                  break;
              }
          }
          else
          {
              //find right
              auto rloc = it.first + Location{ 1, 0 };
              while (chars.count(rloc))
              {
                  auto& rsf = chars.at(rloc);
                  auto rc = rsf.GetCharacter({ 0, 0 });
                  if (rc && (*rc)[0] == wide_character_filler)
                  {
                      selected_chars_fixed[rloc] = rsf;
                      rloc = rloc + Location{ 1, 0 };
                      continue;
                  }
                  break;
              }
          }
      }
  
      selected_chars = move(selected_chars_fixed);
  
      for (auto& it : selected_chars)
      {
          not_selected_chars.erase(it.first);
      }
  }
  
  void SurfaceInstance::MergeSelectCache()
  {
      chars = not_selected_chars;
      for (auto& it : selected_chars)
      {
          //if (chars.count(it.first))
          //    chars[it.first].SetCharacter(it.second, { 0, 0 });
          //else
              chars[it.first] = it.second;
      }
  }
  
  }