Improving code for Managing ASCii Characters For LCD Display

The Button and Encoder input is easy.
What I’m working on is to be able to choose the next/previous characters with spaces and periods as needed.
Also I need functionality like shift and periods

Object is to use a LCD display to provide a user input with either buttons or encoder. the input would be for setting a password or other text based entries.

The following code works well but it seems to be messy and can be confusing.
The goals is to use a small footprint because of the memory limitations of the ATMEGA328p chip (UNO)
and be funcitonal.

At this time this code is the functioning correctly.

Parameters:
C: Character to start with
offset: any number positive or negative or even zero. will be constrained to increment only by 1 character
mode: Sets the available set of characters/numbers available to use
0 Numbers 9876543210
1 all zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA9876543210
2 Letters only yxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA
3 Numbers and Small Letters zyxwvutsrqponmlkjihgfedcba9876543210
4 Small Letters zyxwvutsrqponmlkjihgfedcba
5 Numbers and Capital Letters ZYXWVUTSRQPONMLKJIHGFEDCBA9876543210
6 Capital Letters ZYXWVUTSRQPONMLKJIHGFEDCBA
AddSpace: Makes a space or period available to choose from zyxwvutsrqponmlkjihgfedcba 9876543210.
SwitchCase: Either toggles between case when all letters are available or acts like s shift key when restricted to one case or the other.

Returns
altered character based on parameters.

char CharPicker(char C,int offset,int mode,bool AddSpace, bool SwitchCase){ 
	static char LastC;
	mode = constrain(mode, 0, 6);
	char Limits[7][12]{// the following are jumps in the ASCii characters
			{123,48, 91,48,  58,48,  47,57 , 96,57,  64,57 },  // 0 Numbers                      9876543210.
			{ 58,65, 91,97,  123,48, 47,122, 96,90,  64,57 },  // 1 all                          zyxwvutsrqponmlkjihgfedcba ZYXWVUTSRQPONMLKJIHGFEDCBA 9876543210.
			{ 58,65, 91,97,  123,65, 64,122, 96,90,  64,122},  // 2 Letters only                 yxwvutsrqponmlkjihgfedcba ZYXWVUTSRQPONMLKJIHGFEDCBA
			{ 58,97, 91,97,  123,48, 47,122, 96,57,  64,57 },  // 3 Numbers and Small Letters    zyxwvutsrqponmlkjihgfedcba 9876543210.
			{ 58,97, 91,97,  123,97, 96,122, 96,122, 64,122},  // 4 Small Letters                zyxwvutsrqponmlkjihgfedcba
			{ 58,65, 91,48,  123,48, 47, 90, 96,90,  64,57 },  // 5 Numbers and Capital Letters  ZYXWVUTSRQPONMLKJIHGFEDCBA 9876543210.
			{ 91,65, 91,65,   91,65, 64, 90, 64,90,  64,90 }   // 6 Capital Letters              ZYXWVUTSRQPONMLKJIHGFEDCBA 
	};
	int x = (C>64) + (C > 96); // 0 = Num, 1 = Cap, 2 = Small
	int y = (mode >= 3) + (mode >= 5); // 1 = Caps Only, 2 = Smalls Only
	if ((y == 1) && (x == 1)) C = (C < 65) ? C : ((C >= 97) ? C - 32 : C + 32 ); // We are supposed to be Caps but we recieved a small letter
	if ((y == 2) && (x == 2)) C = (C < 65) ? C : ((C >= 97) ? C - 32 : C + 32 ); // We are supposed to be Smalls but we recieved a Capital letter
	if(AddSpace){
		if((C == 32) || (C == 46)) { // last character was a space or a period.
			C = LastC; // go back to the prior character.
		} else {
			char CC = C + constrain(offset, -1,1);
			if (CC == 64 || CC == 96 || CC == 91 || CC == 123 ){ // Just outside letters
				return(32);
			}
			if (CC == 47 || CC == 58){ // Just outside numbers
				return(46);
			}
		}
	}
	C = C + constrain(offset, -1,1); //Change one letter
	C = (C == Limits[mode][0]) ? Limits[mode][1]:((C == Limits[mode][2]) ? Limits[mode][3] : ((C >= Limits[mode][4]) ? Limits[mode][5] : C));   //Skip Non Letters and Numbers
	C = (C <= Limits[mode][6]) ? Limits[mode][7]:((C == Limits[mode][8]) ? Limits[mode][9] : ((C == Limits[mode][10]) ? Limits[mode][11] : C)); //Skip Non Letters and Numbers
	if (SwitchCase) {
		C = (C < 65) ? C : ((C >= 97) ? C - 32 : C + 32 ); // Switch to other case 
	}
	LastC = C; // Store current character
	return(C);
}

Please post ideas as to how to refine this code and feel free to use my version or any alterations that come from this.

My test code:

char * MList[7] = {
 " 0 Numbers"
," 1 all    "
," 2 Letters"
," 3 NuSmall"
," 4 Small  "
," 5 NuCaps "
," 6 Caps   "};
void setup() {
  Serial.begin(115200);
  static char C;
  for (int Mode = 0; Mode <= 6; Mode++) {
    for (int SwitchCase = 0; SwitchCase <= 1; SwitchCase++) {
      for (int Dir = -1; Dir <= 1; Dir++) {
        C = 0;
        Serial.println();
        Serial.print(MList[Mode]);
        Serial.print(F("\t Shift:"));
        Serial.print(SwitchCase);
        Serial.print(F("\t Direction:"));
        Serial.print(Dir);
        Serial.print(F("\t"));

        delay(100);
        for (int i = 0; i < 78; i++) {
          C = CharPickerS(C, Dir, Mode,true, SwitchCase);
          Serial.print(C);
        }
      }
    }
  }
  while (1);
}

void loop() {
}

//Place complete function here:
char CharPicker(char C,int offset,int mode,bool AddSpace, bool SwitchCase){ 
}

Thanks in advance