/*
**
** Copyright (C) 1994 Swedish University Network (SUNET)
**
**
** This program is developed by UDAC, Uppsala University by commission
** of the Swedish University Network (SUNET). 
**
** 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 FITTNESS 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.
**
**
**                                        Martin.Wendel@udac.uu.se
**                                        Torbjorn.Wictorin@udac.uu.se
**
**                                        UDAC	
**                                        P.O. Box 174
**                                        S-751 04 Uppsala
**                                        Sweden
**
*/


#include "emil.h"

int
convert_data(struct message *m)
{
  int status;
  if (target == NULL || source == NULL)
    return(NOK);

#ifdef DEBUG
  if (edebug)
    fprintf(stderr, "* Converting data level: %i\n", m->level);
#endif

  if (m->type == NULL)
    {
#ifdef DEBUG
      if (edebug)
	fprintf(stderr, "+ no type (TEXT)\n");
#endif

      m->type = NEWSTR("TEXT");
}

  /* Start at the beginning */
  m->td->offset = m->td->bodystart;

  /* Check for 8bit data */
  if (m->td->encoding == E7BIT)
    check_bits(m->td);
#ifdef DEBUG
  if (edebug)
    fprintf(stderr, "* Recoding data\n");
#endif

  while ((status = recode_data(m)) != OK)
    m->td->offset = m->td->bodystart;
    ;

#ifdef DEBUG
  if (edebug)
    fprintf(stderr, "* Encode header\n");
#endif

  encode_header(m);

  /* Recursion over children and siblings */
  if (m->child != NULL)
    {
      logger(LOG_DEBUG, "convert_data: Converting child");
    (void) convert_data(m->child);
    }
  if (m->sibling != NULL)
    {
      logger(LOG_DEBUG, "convert_data: Converting sibling");
    (void) convert_data(m->sibling);
    }
  return(OK);
}




int
recode_data(struct message *m)
{
  switch(m->td->encoding)
    {
    case E7BIT:
#ifdef DEBUG
  if (edebug)
    fprintf(stderr, "-   is 7bit\n");
#endif
      
      if (m->td->charset == NULL)
	{
#ifdef DEBUG
	  if (edebug)
	    fprintf(stderr, "*   no charset (US-ASCII)");
#endif

	  m->td->charset = NEWSTR("US-ASCII");
	}
      if (tocharset(m) == OK)
	check_bits(m->td);

      if (m->td->encoding != E7BIT)
	return(NOK);
      /* Default */
      return(OK);
      break;

    case E8BIT:
#ifdef DEBUG
  if (edebug)
    fprintf(stderr, "-   is 8bit\n");
#endif
      if (m->td->charset == NULL)
	{
	  m->td->charset = source->charset == NULL ? NEWSTR("ISO-8859-1") :
	    source->charset;
#ifdef DEBUG
  if (edebug)
    fprintf(stderr, "*   no charset (%s)\n", m->td->charset);
#endif

	}
      if (tocharset(m) == OK) /* Handle charset conversion first */
	check_bits(m->td);

      if (m->td->encoding != E8BIT)
	return(NOK);

      /* Convert to target text encoding */
      switch (target->itext)
	{
	case EQP:
	  encode_quoted_printable(m);
	  break;
	case EBINHEX:
	  encode_binhex(m);
	  break;
	case EUUENCODE:
	  encode_uuencode(m);
	  break;
	case EBASE64:
	  encode_base64(m);
	  break;
	default:
	  break;
	}
      return(OK);
      break;

    case EQP:
      /* Convert to target charset and possibly decode or encode
       * to quoted-printable.
       */
#ifdef DEBUG
  if (edebug)
    fprintf(stderr, "-   is qp\n");
#endif
      
      if (target->itext != EQP || 
	  ((target->charset != NULL) && 
	   (cmatch(target->charset, m->sd->charset) == FALSE)))
	{
	  if (decode_quoted_printable(m) == OK)
	    {
	      check_bits(m->td);
	      return(NOK);
	    }
	  return(OK);
	}
      else
	return(OK);
      break;

    case EBINARY:
#ifdef DEBUG
  if (edebug)
    fprintf(stderr, "-   is binary\n");
#endif
      switch(target->ibin)
	{
	case EBINHEX:
	  encode_binhex(m);
	  return(OK);
	  break;
	case EUUENCODE:
	  encode_uuencode(m);
	  return(OK);
	  break;
	case EBASE64:
	  encode_base64(m);
	  return(OK);
	  break;
	default:
	  /* Fail */
	  m->td = m->sd;
	  return(OK);
	  break;
	}
      break;

    case EBINHEX:
      /* Check if source and target binary format is equal
       * Else convert here 
       */
#ifdef DEBUG
  if (edebug)
    fprintf(stderr, "-   is BinHex\n");
#endif
      if (target->ibin != EBINHEX)
	{
	  if (decode_binhex(m) == OK)
	    return(NOK);
	  return(OK);
	}
      else
	return(OK);
      break;

    case EUUENCODE:
      /* Check if source and target binary format is equal
       * Else convert here 
       */
#ifdef DEBUG
  if (edebug)
    fprintf(stderr, "-   is UUencode\n");
#endif
      if (target->ibin != EUUENCODE)
	{
	  if (decode_uuencode(m) == OK)
	    return(NOK);
	  else
	    return(OK);
	}
      else
	return(OK);
      break;

    case EBASE64:
      /* Check if source and target binary format is equal
       * Else convert here 
       */
#ifdef DEBUG
  if (edebug)
    fprintf(stderr, "-   is base64\n");
#endif
      if (target->ibin != EBASE64)
	{
	  if (decode_base64(m) == OK)
	    return(NOK);
	  return(OK);
	}
      else
	return(OK);
      break;

    case EMULTI:
#ifdef DEBUG
  if (edebug)
    fprintf(stderr, "-   is multi\n");
#endif
      /* This is not convertable */
      return(OK);
      break;

    default:
#ifdef DEBUG
  if (edebug)
    fprintf(stderr, "*   is unknown (skip or check)\n");
#endif
      /* Ignore, possibly some error has occurred */
      check_bits(m->td);
      return(OK);
      break;
    }
  return(NOK);
}




