#include <algorithm>
#include <map>
#include "MyString.h"

MyString::MyString(string s){
  this->s = s;
}

void MyString::setS(string str){
  this->s = str;
}

string MyString::getS(){
  return s;
}

MyString MyString::removePunctuation(){
  string result;
  remove_copy_if(s.begin(), s.end(), back_inserter(result), std::ptr_fun<int, int>(ispunct));
  return MyString(result);
}

MyString MyString::toUpper(){
  string temp = this->s;
  transform(temp.begin(), temp.end(), temp.begin(),::toupper);
  return MyString(temp);
}

MyString MyString::reverse(){
  string temp = this->s;
  int n = temp.length();
  for (int i = 0; i < n/2; i++)
      swap(temp[i], temp[n-i-1]);
  return MyString(temp);
}

MyString MyString::toMirror(){
  string str = this->s;
  for(int i=0; i<str.size(); i++){
    int pos = normal.find(str[i]);
    if(mirror[pos] != ' '){
      //cout << "Found! " << mirror[pos] << endl;
      str[i] = mirror[pos];
    }
  }
  return MyString(str);
}

void showMyStringType(){
  //Show Type
}

MyString MyString::longestPeekPalindrome(){
  string str = this->s;
  int n = str.size();
  bool palCheckTab[n][n];
  for(int i = 0; i<n; i++)
     for(int j = 0; j<n; j++)
        palCheckTab[i][j] = false;
  int maxLength = 1;
  for(int i = 0; i < n; ++i)
     palCheckTab[i][i] = true;
  int start = 0;
  for(int i = 0; i < n-1; ++i){
     if(str[i] == str[i+1]){
        palCheckTab[i][i+1] = true;
        start = i;
        maxLength = 2;
     }
  }
  for(int k = 3; k <= n; ++k){
     for(int i = 0; i < n-k+1 ; ++i){
        int j = i + k - 1;
        if(palCheckTab[i+1][j-1] && str[i] == str[j]){
           palCheckTab[i][j] = true;
           if(k > maxLength) {
              start = i;
              maxLength = k;
           }
        }
     }
  }
  str = str.substr(start, maxLength);
  return MyString(str);
}

void MyString::checkStringType(){
  map<char, char> M;
  for(int i=0; i<normal.size(); i++){
    M[normal[i]] = mirror[i];
  }
  bool palin, mirror;
  palin = mirror = true;
  string str = this->s;
  int n = str.size();
  for(int i=0; i<=n/2; i++){
    if(str[i] != str[n-i-1]){
      palin = false;
    }
    if(str[n-i-1] != M[str[i]]){
      mirror = false;
    }
  }
  if(palin && mirror){
    cout << "Both" << endl;
  }else if(palin && !mirror){
    cout << "Normal" << endl;
  }else if(!palin && mirror){
    cout << "Mirror" << endl;
  }else{
    cout << "Neither" << endl;
  }
}