#include <textmenu.h>
#include <function.h>

CORRECTFUN Correct_String;
MODE DELAFTER1=YES; // Уничтожать строку после 1 цифрового символа

int strlen__ (MODE *str, MODE *kol) {
 // Длина строки без символов '\n','$' (перевод строки и смена цвета)
 // Возвращает длину максимальной подстроки и
 // количество подстрок через параметр *kol
 MODE *ptr=str;
 MODE mcol=0,i=0;
 (*kol)=1;
 for (;*ptr!='\0'; ptr++) {
  if (*ptr=='\n') {
   if (i>mcol) mcol=i; i=0; (*kol)++;
  }
  else if (*ptr!='$') i++;
 }
 if (i==0) (*kol)--;
 if (i>mcol) mcol=i;
 return (mcol);
}

////// Часть для ввода строки
char isdigit(char c) {
 if (c>47 && c<58 ) return (1);
 return (0);
}
char isspace(char c) {
 if ((c>0x08 && c<0x0e) || c==0x20) return 1;
 return 0;
}
char isascii (char c) {
 if (c>31 && c<255) return 0x01;
 return 0x00;
}
MODE isunsigned (MODE *ptr) {
 // Проверяет, является ли строка записью целого беззнакового числа
 // Возвращает 0 или 1
 MODE Ret=1;
 while (*ptr==' ' || *ptr=='\t') ptr++;
 if (*ptr=='\0') return 0;
 for (; *ptr; ptr++) if (!isdigit(*ptr)) { Ret=0; break; }
 return Ret;
}
MODE isnumber(MODE *str) {
 // Проверяет, является ли строка записью числа в одном из целых или
 // вещественных форматов. Возвращает 0 или 1
 MODE *ptr=str;
 MODE Point=0x00,E=0x00;
 while (*ptr==' ' || *ptr=='\t') ptr++;
 if (*ptr=='\0') return 1; // Допускается строка из пробелов!
 if (*ptr=='-'||*ptr=='+') ptr++;
 for (;*ptr; ptr++) {
  if (!isdigit(*ptr)) {
   switch (*ptr) {
    case '.':
     if (Point) return 0;
     else Point=0x01;
    break;
    case 'e':
    case 'E':
     if (E) return 0;
     else E=0x01;
    break;
    case '+':
    case '-':
     if (Point && E) break;
     else return 0;
    default: return 0;
   }
  }
 }
 return 1;
}

char Correct_Date (char *Str, KEY c, int pos) {
 // Проверка ввода даты ДД-ММ-ГГ
 switch (pos) {
  case 0: case 3:
   if (c==' ') *(Str+pos)='0';
   else if (!isdigit(c)) return NO;
  break;
  case 6: case 7:
   if (!isdigit(c)) return NO;
  break;
  case 1: case 4:
   if (!isdigit(c)) return NO;
   Set_Key (1,RIGHT);
  break;
  case 2: case 5: if (c!='-') return NO;
  break;
  default: return NO;
 }
 return YES;
}

char Correct_Number (char *Str, KEY c, int pos) {
 if (isnumber(Str) && (isdigit(c) ||  (c=='-' && Str[0]!='-')))
  return 0x01;
 return 0x00;
}

char Correct_Ascii (char *Str, KEY c, int pos) {
 return (isascii(c));
}

void toupper_ (MODE *Str) {
 MODE c;  int i;
 for (i=0; *(Str+i); i++) {
  c=*(Str+i);
  if (c>96 && c<123 || c>159 && c<176) c-=32; // a-z, а-п
  else if (c>223 && c<240) c-=80; // р-я
  *(Str+i)=c;
 }
 return;
}

void tolower_ (MODE *Str) {
 MODE c;  int i;
 for (i=0; *(Str+i); i++) {
  c=*(Str+i);
  if (c>64 && c<91 || c>127 && c<144) c+=32; // A-Z, А-П
  else if (c>143 && c<160) c+=80; // Р-Я
  *(Str+i)=c;
 }
 return;
}

void LeftMargin (MODE *String) { // убрать пробелы слева
 int i,k=0;
 while (String[k]==' ' || String[k]=='\t') k++;
 if (k) for (i=0; ; i++) {
  String[i]=String[i+k];
  if (String[i+k]=='\0') break;
 } return;
}

void LeftSide (MODE *String, int Field) {
 // Выровнять строку по левому краю в поле [Field]
 int i;
 LeftMargin(String);
 i=strlen_ (String);
 while (i<Field) { *(String+i)=' '; i++; } // ... дописать строку
 *(String+Field)='\0';
 return;
}

void RightMargin (MODE *String) { // убрать пробелы справа
 int k=strlen_(String)-1;
 if (k>=0) while (*(String+k)==' ' || *(String+k)=='\t') {
  String[k]='\0'; k--; if (k<0) break;
 } return;
}

void RightSide (MODE *String, int Field) {
// Выровнять строку по правому краю в поле [Field]
 int i,k,d;
 LeftMargin(String); RightMargin(String);
 i=strlen_(String);
 if (i>Field) {
  d=i-Field;
  for (k=0; k<Field; k++) String[k]=String[d+k];
 }
 else if (i<Field) {
  d=Field-i;
  for (k=Field-1; k>=d; k--) String[k]=String[k-d];
  for (k=0; k<d; k++) String[k]=' ';
 }
 String[Field]='\0';
 return;
}

int atoi_ (MODE *s) {
 int n,sign;
 for (; isspace(*s); s++);
 sign=(*s=='-' ? -1 :1);
 if (*s=='+'||*s=='-')s++;
 for (n=0;isdigit(*s);s++) n=10*n+*s-'0';
 return (sign*n);
}
long atol_ (MODE *s) {
 long n;
 for (; isspace(*s); s++);
 for (n=0;isdigit(*s);s++) n=10*n+*s-'0';
 return n;
}
void infcpy_ (MODE *d, MODE *s) {
 //Копирование без конца строки '\0'
 while (*s) *d++=*s++;
}
void strcpy_ (MODE *d, MODE *s) {
 while (*s) *d++=*s++;
 *d='\0';
}
void strcat_ (MODE *d, MODE *s) {
 while (*d) d++;
 while (*s) *d++=*s++;
 *d='\0';
}

MODE *strchr_ (MODE *s, MODE c) {
 while (*s) {
  if (*s==c) return s;
  s++;
 }
 return 0;
}
MODE *strrchr_ (MODE *s, MODE c) {
 MODE *p=0;
 while (*s) {
  if (*s==c) p=s;
  s++;
 }
 return p;
}
unsigned strlen_(MODE *s) {
 unsigned l=0;
 while (*s!='\0') { l++; s++; }
 return l;
}
unsigned strpos_ (MODE *str,MODE c) {
 //Возвращает позицию в строке символа c или '\0'
 unsigned l=0;
 while (!(*(str+l)=='\0' || *(str+l)==c)) l++;
 return l;
}
void strset_ (MODE *s, MODE c, unsigned kol) {
 //Устанавливает в kol байт строки s значение c
 unsigned u;
 for (u=0; u<kol; u++) *(s+u)=c;
}
void strrev_(MODE *s) {
 int c; char *t;
 for (t=s+strlen_(s)-1; s<t; s++,t--) {
  c=*s; *s=*t; *t=c;
 }
}
void memcpy_ (MODE *d, MODE *s, unsigned n) {
 unsigned i;
 for (i=0; i<n; i++) *d++=*s++;
}
void memset_ (MODE *s, MODE c,unsigned n) {
 unsigned i;
 for (i=0; i<n; i++) *s++=c;
}

void itoa_ (int n, MODE *s) {
 int sign;
 MODE *t=s;
 if ((sign=n)<0) n=-n;
 do {
  *s++=n%10+'0';
 } while ((n/=10)!=0);
 if (sign<0) *s++='-';
 *s='\0';
 strrev_ (t);
}
void ultoa_ (unsigned long n, MODE *s) {
 MODE *t=s;
 do {  *s++=n%10+'0'; } while ((n/=10)!=0);
 *s='\0';
 strrev_ (t);
}
static MODE StackByte;
void Push (MODE *Ptr) { StackByte=*Ptr; *Ptr='\0'; return; }
void Pop (MODE *Ptr) { *Ptr=StackByte; return; }

