/* 
 * This finds all the global colorizer tags, splits up the text into arrays,
 * runs it through the colorizer code, then re-assembles it.
 *
 * To Do:
 * Rewrite and use pointers to save memory
 */
char *do_gcolorize ( char *arg, CHAR_DATA * ch )
{
  /* Giant buffers */
  static char buf[MAX_OUT];
  char colorbuf[MAX_OUT];
  char tempbuf[MAX_OUT];

  char gidstr[10];

  char argument[MAX_OUT + 10];

  sprintf ( argument, "%s{}", arg );

  /*
   * Giant memory-sucking multi-dimensional arrays
   * where we store, process and re-assmble the string
   */
  char beginstr[MAX_OUT][maxtags];      /* Text before the colorizer */
  char colorstr[MAX_OUT][maxtags];      /* Text being colored */
  char endstr[MAX_OUT][maxtags];        /* Text after the colorizer */

  /* Arrays to hold all the tag positions and the colorizer number */
  long open[maxtags], close[maxtags], reset[maxtags], gid[maxtags];

  /*
   * Tons of increment / position ints
   * Needs to be cleaned up...
   */
  long i = 0, o = 0, c = 0, r = 0, x = 0, gpos = 0, pos = 0, cpos = 0, spos = 0, epos = 0, bufpos = 0, tstart = 0, otemp = 0;

  memset ( gidstr, 0, 10 );

  /* Initalize our tag data arrays */
  for ( i = 0; i < maxtags; i++ )
  {
    open[i] = 0;
    close[i] = 0;
    reset[i] = 0;
    gid[i] = 0;
  }

  /*
   * Find all the tag positions (start, end and reset)
   * for each tag in the string and put them into our arrays
   * 
   * We have to know this so we can
   * 1: Get the number from the tag so we know what colorizer to use.
   * 2: Remove the tag characters from the text.
   * 3: Divide the string up, store it, colorize it and re-assemble it.
   */
  for ( i = 0; i < MAX_OUT && argument[i] != '\0'; i++ )
  {
    if ( argument[i] == '{' && ( argument[( i + 1 )] >= '0' && argument[( i + 1 )] <= '9' ) )
    {
      if ( i > 0 && argument[( i - 1 )] == '{' )
        continue;

      open[o] = ( i + 1 );
      o++;
    }
    else if ( argument[i] == '}' && ( argument[( i - 1 )] >= '0' && argument[( i - 1 )] <= '9' ) )
    {
      if ( o > 0 )
      {
        close[( o - 1 )] = ( i + 1 );
        c++;
      }
    }
    else if ( argument[i] == '{' && argument[( i + 1 )] == '}' )
    {
      if ( i > 0 && argument[( i - 1 )] == '{' )
        continue;

      if ( o > 0 )
      {
        reset[( o - 1 )] = i;
        r++;
      }
    }

  }

  /* Grab global colorizer numbers from tags */
  if ( o > 0 && c > 0 && c == o )
  {
    for ( i = 0; i < maxtags; i++ )
    {
      gpos = 0;
      /*
       * We look between the start of the tag and the end of the tag
       * so we can get the number from it
       *
       * Then we store the data into a string and convert it into a number.
       * Then that number is stored into an array so we can tell do_colorize()
       * what colorizer we want to use when we're processing the text
       */
      for ( x = open[i]; x <= close[i] && gpos < 9; x++ )
      {
        gidstr[gpos] = argument[x];
        gpos++;
      }

      gidstr[gpos] = '\0';
      if ( gidstr[0] != '\0' )
      {
        gid[i] = atoi ( gidstr );
      }
    }

    /*
     * Seperate the string data and store it in huge arrays.
     * This takes way too much effort...
     */
    bufpos = 0;
    for ( i = 0; i < maxtags; i++ )
    {
      /* Clear all this crap */
      bool truereset = FALSE;

      beginstr[0][i] = '\0';
      colorstr[0][i] = '\0';
      endstr[0][i] = '\0';

      /*
       * We make sure there is data in the tags before we start
       * We set truereset to TRUE, but if we do not detect a manual reset []
       * we set it to FALSE later on
       *
       * We set the next tag's open position even if there is no next tag,
       * because we need that data when we put all the data into the arrays.
       * 
       * If there is no manual reset, we set the reset position to the next tag's start position
       * If there is no next tag, we set the reset position to the end of the string
       */
      if ( open[i] < close[i] )
      {
        if ( reset[i] > 0 )
          truereset = TRUE;

        if ( open[( i + 1 )] == 0 )
        {
          open[( i + 1 )] = ( strlen ( argument ) );
        }
        if ( reset[i] == 0 )
        {
          if ( open[( i + 1 )] > 0 )
            reset[i] = ( open[( i + 1 )] - 1 );
          else
            reset[i] = ( strlen ( argument ) );

          truereset = FALSE;
        }

        /*
         * Put data into the arrays
         */

        /* Color array */
        cpos = 0;
        for ( pos = close[i]; pos < reset[i]; pos++ )
        {
          colorstr[cpos][i] = argument[pos];
          cpos++;
        }
        colorstr[cpos][i] = '\0';

        /* Begining array */
        /*
         * If we are on the first tag we start at the begining of the string.
         * Otherwise we start at the previous tag's reset position.
         * The previous tag's reset position is either a manual reset, or us.
         */
        spos = 0;
        if ( i > 0 )
          tstart = reset[( i - 1 )];
        else
          tstart = 0;
        /*
         * If this is a manual reset and we're not on the first tag
         * we end at the start of our tag.
         */
        if ( truereset && i > 0 )
          tstart = close[i];
        /* Copy the string into the array, skipping the start of the tag */
        for ( pos = tstart; pos < ( open[i] - 1 ); pos++ )
        {
          beginstr[spos][i] = argument[pos];
          spos++;
        }
        beginstr[spos][i] = '\0';

        /* Ending array */
        epos = 0;
        /* If it is a truereset ( manual reset: [] ) then we skip over the [] chars */
        if ( truereset )
          otemp = ( reset[i] + 2 );
        else
          otemp = reset[i];
        /*
         * Copy the text into the array and stop when we get to the next tag's start
         * Code before us sets this data for us if there is no next tag
         */
        for ( pos = otemp; argument[pos] != '\0' && pos < ( open[( i + 1 )] - 1 ); pos++ )
        {
          endstr[epos][i] = argument[pos];
          epos++;
        }
        endstr[epos][i] = '\0';

        /*
         * We copy the data out of the color array into a standard string
         * so we can pass it through do_colorize()
         */
        colorbuf[0] = '\0';
        if ( colorstr[0][i] != '\0' )
        {
          for ( x = 0; colorstr[x][i] != '\0' && x < MSL; x++ )
            tempbuf[x] = colorstr[x][i];

          tempbuf[x] = '\0';


          sprintf ( colorbuf, "%s", IS_SET ( ch->act2, PLR2_NOCOLORIZERS ) ? tempbuf : do_colorize ( tempbuf,
              get_gcolorizer ( gid[i] ), FALSE ) );
        }

        /* Re-assemble everything into the buffer, making sure not to overflow. */
        for ( pos = 0; beginstr[pos][i] != '\0' && bufpos < MSL; pos++ )
        {
          buf[bufpos] = beginstr[pos][i];
          bufpos++;
        }
        for ( pos = 0; colorbuf[pos] != '\0' && bufpos < MSL; pos++ )
        {
          buf[bufpos] = colorbuf[pos];
          bufpos++;
        }
        for ( pos = 0; endstr[pos][i] != '\0' && bufpos < MSL; pos++ )
        {
          buf[bufpos] = endstr[pos][i];
          bufpos++;
        }
      }
    }

    /* Add end marker to the buffer */
    buf[bufpos] = '\0';
    /* Send it off */
    return buf;
  }
  else
  {
    /* No colorizer tags, pass unedited argument */
    sprintf ( buf, "%s", argument );
  }
  return buf;
}

