/****************************************************************************/
/* WebWorks Help API                                                        */
/*                                                                          */
/*                                                                          */
/****************************************************************************/

/*$Id: wwhurl.c,v 1.15 2006/11/29 19:24:38 allums Exp $*/


#include "wwhelp/wwhurl.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


/****************************************************************************/
/* WWHelp_URL_EscapeForJavaScript                                           */
/*                                                                          */
/*   Escape given URL so that it can be embedded in a JavaScript URL.       */
/*                                                                          */
/****************************************************************************/

int
WWHelp_URL_EscapeForJavaScript(const char*   pParamURL,
                               const size_t  ParamURLLength,
                                     char**  hParamEscapedURL,
                                     size_t* pParamEscapedURLLength)
{
  int     ReturnCode = -1;
  size_t  Index;
  char*   pEscapedURL;
  size_t  EscapedIndex;


  /* Reset escape URL parameters */
  /*                             */
  *hParamEscapedURL = NULL;
  *pParamEscapedURLLength = 0;

  if ((pParamURL != NULL) &&
      (ParamURLLength > 0))
  {
    /* Allocate max possible size for escaped URL buffer */
    /*                                                   */
    pEscapedURL = (char*)malloc((3 * ParamURLLength + 1) * sizeof(char));
    if (pEscapedURL != NULL)
    {
      /* Process URL into escaped URL buffer */
      /*                                     */
      EscapedIndex = 0;
      for (Index = 0 ; Index < ParamURLLength ; Index++)
      {
        switch (pParamURL[Index])
        {
          case '"':
            memcpy(&(pEscapedURL[EscapedIndex]), "%22", 3);
            EscapedIndex += 3;
            break;

          case '%':
            memcpy(&(pEscapedURL[EscapedIndex]), "%25", 3);
            EscapedIndex += 3;
            break;

          case '&':
            memcpy(&(pEscapedURL[EscapedIndex]), "%26", 3);
            EscapedIndex += 3;
            break;

          case '\'':
            memcpy(&(pEscapedURL[EscapedIndex]), "%27", 3);
            EscapedIndex += 3;
            break;

          case '?':
            memcpy(&(pEscapedURL[EscapedIndex]), "%3f", 3);
            EscapedIndex += 3;
            break;

          case '\\':
            memcpy(&(pEscapedURL[EscapedIndex]), "%5c", 3);
            EscapedIndex += 3;
            break;

          default:
            pEscapedURL[EscapedIndex] = pParamURL[Index];
            EscapedIndex += 1;
            break;
        }
      }

      if (EscapedIndex > 0)
      {
        /* NULL terminate buffer and trim excess size */
        /*                                            */
        pEscapedURL[EscapedIndex] = '\0';
        *pParamEscapedURLLength = EscapedIndex;
        *hParamEscapedURL = (char*)malloc((*pParamEscapedURLLength + 1) * sizeof(char));
        memcpy(*hParamEscapedURL, pEscapedURL, *pParamEscapedURLLength + 1);

        ReturnCode = 0;
      }

      free(pEscapedURL);
    }
  }

  return ReturnCode;
}


/****************************************************************************/
/* WWHelp_URL_Unescape                                                      */
/*                                                                          */
/*   Unescape given URL.                                                    */
/*                                                                          */
/****************************************************************************/

int
WWHelp_URL_Unescape(const char*   pParamURL,
                    const size_t  ParamURLLength,
                          char**  hParamUnescapedURL,
                          size_t* pParamUnescapedURLLength)
{
  int     ReturnCode = -1;
  char*   pHexidecimalValue;
  char*   pUnescapedURL;
  size_t  UnescapedIndex;
  size_t  Index;
  int     UnescapedCharacterCode;


  /* Reset escape URL parameters */
  /*                             */
  *hParamUnescapedURL = NULL;
  *pParamUnescapedURLLength = 0;

  /* Create storage for hexidecimal values */
  /*                                       */
  pHexidecimalValue = (char*)malloc(3 * sizeof(char));

  if ((pHexidecimalValue != NULL) &&
      (pParamURL != NULL) &&
      (ParamURLLength > 0))
  {
    /* Allocate max possible size for unescaped URL buffer */
    /*                                                     */
    pUnescapedURL = (char*)malloc((3 * ParamURLLength + 1) * sizeof(char));
    if (pUnescapedURL != NULL)
    {
      /* Process URL into unescaped URL buffer */
      /*                                       */
      UnescapedIndex = 0;
      for (Index = 0 ; Index < ParamURLLength ; Index++)
      {
        switch (pParamURL[Index])
        {
          case '%':
            /* Convert to a normal character */
            /*                               */
            if ((Index + 2) < ParamURLLength)
            {
              Index++;
              pHexidecimalValue[0] = pParamURL[Index];
              Index++;
              pHexidecimalValue[1] = pParamURL[Index];
              pHexidecimalValue[2] = '\0';

              sscanf(pHexidecimalValue, "%x", &UnescapedCharacterCode);
              pUnescapedURL[UnescapedIndex] = (char)UnescapedCharacterCode;
              UnescapedIndex += 1;
            }
            break;

          default:
            pUnescapedURL[UnescapedIndex] = pParamURL[Index];
            UnescapedIndex += 1;
            break;
        }
      }

      if (UnescapedIndex > 0)
      {
        /* NULL terminate buffer and trim excess size */
        /*                                            */
        pUnescapedURL[UnescapedIndex] = '\0';
        *pParamUnescapedURLLength = UnescapedIndex;
        *hParamUnescapedURL = (char*)malloc((*pParamUnescapedURLLength + 1) * sizeof(char));
        memcpy(*hParamUnescapedURL, pUnescapedURL, *pParamUnescapedURLLength + 1);

        ReturnCode = 0;
      }

      free(pUnescapedURL);
    }

    free(pHexidecimalValue);
  }

  return ReturnCode;
}


/****************************************************************************/
/* WWHelp_URL_BuildSmartIEURL                                               */
/*                                                                          */
/*   Builds a smart URL for use most browsers                               */
/*                                                                          */
/****************************************************************************/

int
WWHelp_URL_BuildSmartURL(const char*   pParamURL,
                         const size_t  ParamURLLength,
                               char**  hParamSmartURL,
                               size_t* pParamSmartURLLength)
{
  const char* pJavaScript1 = "javascript:x=unescape('";
  const char* pJavaScript2 = "');if(typeof(window.WWHFrame)!='undefined'){window.WWHFrame.WWHHelp.fSetContextDocument(x);}";

  int     ReturnCode = -1;
  size_t  JavaScript1Length;
  size_t  JavaScript2Length;
  char*   pEscapedURL;
  size_t  EscapedURLLength;
  size_t  AppendIndex;


  *hParamSmartURL = NULL;
  *pParamSmartURLLength = 0;

  if ((pParamURL != NULL) &&
      (ParamURLLength > 0))
  {
    /* Escape the given URL */
    /*                      */
    if (WWHelp_URL_EscapeForJavaScript(pParamURL, ParamURLLength, &pEscapedURL, &EscapedURLLength) == 0)
    {
      JavaScript1Length = strlen(pJavaScript1);
      JavaScript2Length = strlen(pJavaScript2);

      /* Wrap the required javascript call around the escaped URL */
      /*                                                          */
      *pParamSmartURLLength = JavaScript1Length
                            + EscapedURLLength
                            + JavaScript2Length;
      *hParamSmartURL = (char*)malloc((*pParamSmartURLLength + 1) * sizeof(char));
      if (*hParamSmartURL != NULL)
      {
        /* Copy data into place */
        /*                      */
        AppendIndex = 0;
        memcpy(&((*hParamSmartURL)[AppendIndex]), pJavaScript1, JavaScript1Length);
        AppendIndex += JavaScript1Length;
        memcpy(&((*hParamSmartURL)[AppendIndex]), pEscapedURL, EscapedURLLength);
        AppendIndex += EscapedURLLength;
        memcpy(&((*hParamSmartURL)[AppendIndex]), pJavaScript2, JavaScript2Length);
        AppendIndex += JavaScript2Length;
        (*hParamSmartURL)[AppendIndex] = '\0';

        ReturnCode = 0;
      }

      free(pEscapedURL);
    }
  }

  return ReturnCode;
}
