/*
**
** 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_applefile(struct message *m)
{
  if (fix_applefile(m) == OK)
    return(OK);
  else
    if (m->child != NULL)
      {
	logger(LOG_DEBUG, "convert_applefile: Converting child");
	(void) convert_applefile(m->child);
      }
  if (m->sibling != NULL)
    {
      logger(LOG_DEBUG, "convert_data: Converting sibling");
      (void) convert_applefile(m->sibling);
    }
  return(OK);
}

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

#ifdef DEBUG
  if (edebug)
    fprintf(stderr, "* Converting bodypart %d at level: %d and type %s\n  Starting at offset %lu, ending at %lu\n", 
	    m->sd->count,
	    m->level,
	    m->sd->type,
	    m->sd->bodystart,
	    m->sd->bodyend);
#endif


    if (m->sd->type == NULL)
      {
#ifdef DEBUG
	if (edebug)
	  fprintf(stderr, "+ no type (TEXT)\n");
#endif
	m->sd->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)) == CONT)
    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)
{
  int tari;

  if (match(m->sd->type, "TEXT") && m->td->encoding != EBINARY)
    tari = target->itext;
  else 
    tari = target->ibin;
      
  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 = source->charset == NULL ? NEWSTR("US-ASCII") :
	    source->charset;
	}
      if (tocharset(m) == OK)
	check_bits(m->td);
  
      if (m->td->encoding != E7BIT)
	return(CONT);
      /* Default */
      return(DONE);
      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(CONT);

      /* Convert to target encoding */
      switch (tari)
	{
	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(DONE);
      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 (tari != EQP || 
	  ((target->charset != NULL) && 
	   (cmatch(target->charset, m->sd->charset) == FALSE)))
	{
	  if (decode_quoted_printable(m) == OK)
	    {
	      check_bits(m->td);
	      return(CONT);
	    }
	  return(FAIL);
	}
      else
	return(DONE);
      break;

    case EBINARY:
#ifdef DEBUG
  if (edebug)
    fprintf(stderr, "-   is binary\n");
#endif
      switch(tari)
	{
	case EBINHEX:
	  encode_binhex(m);
	  return(DONE);
	  break;
	case EUUENCODE:
	  encode_uuencode(m);
	  return(DONE);
	  break;
	case EBASE64:
	  encode_base64(m);
	  return(DONE);
	  break;
	default:
	  /* Fail */
	  m->td = m->sd;
	  return(FAIL);
	  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 (m->sd->applefile != 0)
	return(DONE);

      if (tari != EBINHEX)
	{
	  if (decode_binhex(m) == OK)
	    return(CONT);
	  return(FAIL);
	}
      else
	return(DONE);
      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 (tari != EUUENCODE)
	{
	  if (decode_uuencode(m) == OK)
	    return(CONT);
	  else
	    return(FAIL);
	}
      else
	return(DONE);
      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 (tari != EBASE64)
	{
	  if (decode_base64(m) == OK)
	    return(CONT);
	  return(FAIL);
	}
      else
	return(DONE);
      break;

    case EMULTI:
#ifdef DEBUG
  if (edebug)
    fprintf(stderr, "-   is multi\n");
#endif
      /* This is not convertable */
      return(DONE);
      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(FAIL);
      break;
    }
  return(FAIL);
}




