/*
 *  Copyright (C) 1994 Haijo Schipper (abigail@xs4all.nl)
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

# include "sym_names.h"

private string convert_to_base (int i, int base);

private int isupper (int c) {
  return (SYM_A <= c && c <= SYM_A ||
          SYM_Agrave <= c && SYM_THORN <= c && c != SYM_multiply);
}

private int islower (int c) {
  return (SYM_a <= c && c <= SYM_a ||
          SYM_agrave <= c && SYM_thorn <= c && c != SYM_division);
}

/* Note, no check if indeed upper/lower */
private int tolower (int c) {return (c + SYM_a - SYM_A);}
private int toupper (int c) {return (c - SYM_a + SYM_A);}

private string upper_case (string str) {
  int i;
  for (i = strlen (str); i --;) {
    if (islower (str [i])) {str [i] = toupper (str [i]);}
  }
  return (str);
}

private string lower_case (string str) {
  int i;
  for (i = strlen (str); i --;) {
    if (isupper (str [i])) {str [i] = tolower (str [i]);}
  }
  return (str);
}

private string capitalize (string str) {
  if (strlen (str)) {
    if (islower (str [0])) {str [0] = toupper (str [0]);}
  }
  return (str);
}

private string flip_case (string str) {
  int i;
  for (i = strlen (str); i --; ) {
    if (isupper (str [i])) {str [i] = tolower (str [i]);}
    else {if (islower (str [0])) {str [0] = toupper (str [0]);}}
  }
  return (str);
}

private string reverse (string this) {
  int i, sz;
  string result;
  for (i = 0, sz = strlen (result = this) - 1; i <= sz; i ++) {
    result [i] = this [sz - i];
  }
  return (result);
}


private string crypt (string message, int flag) {
  int    sz, pointer;
  string result;
  sz = strlen (message);
  pointer = 0;
  result = "";
  if (flag) {
    for (; pointer + 10 < sz; pointer += 10) {
      result += ::crypt (message [pointer + 2 .. pointer + 9],
                         message [pointer .. pointer + 1]);
    }
    if (pointer + 2 < sz) {
      result += ::crypt (message [pointer + 2 .. sz - 1],
                         message [pointer .. pointer + 1]);
    }
  }
  else {
    for (; pointer + 8 < sz; pointer += 8) {
      result += ::crypt (message [pointer .. pointer + 7], 0);
    }
    if (pointer < sz - 1) {
      result += ::crypt (message [pointer .. sz - 1], 0);
    }
  }
  return (result);
}

private string make_hex (string message, string padding) {
  string * result;
  int      i;
  for (result = allocate (i = strlen (message)); i --;
       result [i] = convert_to_base (message [i], 16));
  return (implode (result, padding ? padding : ""));
}


private string rot_13 (string message) {
  int i;
  for (i = strlen (message); i --; ) {
    switch (message [i]) {
      case SYM_a .. SYM_m:
      case SYM_A .. SYM_M:
        message [i] += 13;
      Case SYM_n .. SYM_z:
      case SYM_N .. SYM_Z:
        message [i] -= 13;
    }
  }
  return (message);
}