#define  INCL_DOSERRORS

#include <os2.h>
#include "bdcalls.h"
#include "bdatt.h"
#include "blkapifn.h"

/***********************START OF SPECIFICATIONS*****************************/
/*                                                                         */
/* SUBROUTINE  NAME: NlsConvertBidiString                                  */
/*                                                                         */
/*  COPYRIGHT: (c) IBM Corp. 1989                                          */
/*                                                                         */
/* DESCRIPTIVE NAME: Convert a Source string from one bidirectional        */
/*                   format to another                                     */
/*                                                                         */
/* FUNCTION: Converts a Source string from one bidirectional format        */
/*           to another. This means that orientation and/or numeric        */
/*           shapes and/or character shaping can be changed. The           */
/*           change is determined by 2 BiDiAttributes, one of the          */
/*           source and the other of the target.                           */
/*                                                                         */
/* NOTES:  If the source and target strings do not overlap, the            */
/*         source is not affected and vice versa.                          */
/*                                                                         */
/* ENTRY POINT: NlsConvertBidiString                                       */
/*     LINKAGE: CALL FAR (dynamic link API)                                */
/*                                                                         */
/* INPUT:(Source,Target,Length,Increment,FromAtt,ToAtt,Reserved)           */
/*          @Source    UCHAR  -pointer to the string to be converted       */
/*          @Target    UCHAR  -pointer to the target string                */
/*          Length     DWORD  -length of the source/target string          */
/*          Increment  DWORD  -cell size                                   */
/*          FromAtt    DWORD  -Bidirectional attributes of source string   */
/*          ToAtt      DWORD  -Bidirectional attributes of target string   */
/*          Reserved   DWORD  -Reserved double word                        */
/*                                                                         */
/* EXIT-NORMAL:  RC=0                                                      */
/*                                                                         */
/* EXIT-ERROR:    RC = ERROR_BIDI_INVALID_LENGTH       -invalid length     */
/*                RC = ERROR_BIDI_INVALID_Increment    -invalid Increment  */
/*                RC = ERROR_BIDI_INVALID_Reserved     -invalid Reserved   */
/*                RC = ERROR_BIDI_INVALID_CSD          -invalid CSD        */
/*                RC = ERROR_BIDI_INVALID_ORIENTATION  -invalid orientation*/
/*                RC = ERROR_BIDI_INVALID_NUM_SHAPE    -invalid numerics   */
/*                RC = ERROR_BIDI_INVALID_LEVEL        -invalid level      */
/*                RC = ERROR_BIDI_INVALID_TYPE_SUPPORT -invalid support    */
/*                                                                         */
/* INTERNAL REFERENCES:                                                    */
/*   LOCAL DATA DEFINITION:                                                */
/*      DWORD     RC              - return code from API                   */
/*      CHAR      numto           - numerics field of ToAtt                */
/*                                                                         */
/*   GLOBAL DATA DEFINITION: NONE                                          */
/*   ROUTINES:               ValidCSD      -performs error checking on     */
/*                                          the CSD of From/To Att         */
/*                           ValidNumerics -performs error checking on     */
/*                                          the numerics of From/To Att    */
/*                           ValidOrient   -performs error checking on     */
/*                                          the orientation of From/To Att */
/*                                          the fields of BiDiAttrib       */
/*                           RCLenInc      -performs error checking on     */
/*                                          Length and Increment           */
/*                           GetByte       -Gets a specific byte of        */
/*                                          BiDiAtts                       */
/* EXTERNAL REFERENCES:                                                    */
/*   ROUTINES:                  NONE                                       */
/*                                                                         */
/*                                                                         */
/**************************END OF SPECIFICATIONS****************************/
USHORT far pascal _loadds NlsConvertBidiString ( PUCHAR Source  ,
                                                 PUCHAR Target  ,
                                                 ULONG Length   ,
                                                 ULONG Increment,
                                                 ULONG FromAtt  ,
                                                 ULONG ToAtt    ,
                                                 ULONG Reserved )

{
    char          numto;      /* numerics field of ToAtt     */
    USHORT        RC;         /* return code from RCBiDiAttr */
    unsigned long i;          /* counter                     */


 /*********************** Start of error checking ****************************/

   if (Reserved!=0)                       /* checking on Reserved             */
      return ERROR_BIDI_INVALID_RESERVED;

   if ((RC=(USHORT) RCLenInc(Length,Increment))!=0)
                                      /* checking on Length and Increment */
      return RC;

   if ( (RC=(USHORT)RCBiDiAttr(FromAtt))!=0 )     /* checking on BidiAtts */
       return RC;

   if ( (RC=(USHORT)RCBiDiAttr(ToAtt))!=0 )     /* checking on BidiAtts */
       return RC;

 /*********************** End   of error checking ****************************/

 /********************* Start of String Conversion ***************************/

 /********* Check if inversion is required **********/

      if (GetByte ((char *)&FromAtt,2) != GetByte ((char *)&ToAtt,2))
         NlsInverseString (Source,Target,Length,Increment);
      else                                /* copy Source to Target as is */
         if (Source<Target)
            for (i=Length;i>0 ;i-- )      /* copy backwards              */
               Target[i-1]=Source[i-1];
         else
            for (i=0;i<Length ;i++ )      /* copy from start to end      */
               Target[i]=Source[i];

 /********* Check if numerics conversion is required **********/

      numto   = GetByte((char *)&ToAtt,1)  & 0xf0;

      if ( ( (GetByte((char *)&FromAtt,1)& 0xf0)!= numto) && (
             (numto = HINDI) || (numto = ARABIC) ) ) /* arabic to hindi */
          NlsConvertBidiNumerics(ToAtt,0L,Target,Target,Length,Increment);

 /********* Check if  shaping is required **********/

      if (   (GetByte ((char *)&FromAtt,0) != GetByte ((char *)&ToAtt,0))
          && (GetByte ((char *)&ToAtt,0)!=PASSTHROUGH)    ){
           RC=NlsShapeBidiString (ToAtt,0L,Target,Target, Length,Increment);
           if (RC!=0)
            return RC;
          }

 /********************* End of String Conversion ***************************/

      return 0;      /* successfully performed */
}
