/*******************************************************************************/
/*                                   Tiny Text Editor                                  */
/*                                                                             */
/*                      Programmed by Y.Nishida    [ Nov.14, 1991 ]  version 1.00          */
/*                      Programmed by N.Okajima    [ Jan.17, 1992 ]  version 1.50          */
/*******************************************************************************/

#include        <stdio.h>
#include        <strings.h>
#include        <ctype.h>
#include        "console.h"
#include        "editor.h"

static int      SelectFlag = 0 ;
static int      BlockTopLine ;
static int      BlockBottomLine ;

static char DoFlags[0x37] = {
        0,1,1,1,1,1,1,0,0,1,0,0,0,0,0,0,
        0,1,1,1,1,0,0,1,1,0,1,0,0,0,1,1,
        0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,
        0,0,1,0,0,0,0
} ;

static void DisplayBLOCK() ;
static void ClearBLOCK() ;

/************************************************************************/
/*      Set TextBlock                                                   */
/************************************************************************/

extern int SetTextBlock()
{
        int     code ;

        DisplayBLOCK() ;
        SelectFlag   = 1 ;
        BlockTopLine = CurrentLine ;
        code         = InputChar() ;

        while ( SelectFlag ) {
                if ( code >= 0x200 ) {
                        code = GotoLine( code-0x200 ) ;
                }
                else if ( code >= 0x100 && DoFlags[code-0x100] == 1 ) {
                        code = (*CommandProcess[code-0x100])(code) ;
                }
                else if( code==0x11D ) {
                        SelectFlag = 0;
                        ClearBLOCK();
                        code = InputChar() ;
                }
                else {
                        code = InputChar() ;
                }
        }
        return ( code ) ;
}

/************************************************************************/
/*      Display "BLOCK" into Information area                           */
/************************************************************************/

static void DisplayBLOCK()
{
        strcpy( Information+27,"BLOCK" ) ;
        Information[32] = ' ' ;
        Locate( 0,0 ) ;
        PrintMessage( Information ) ;
        Locate( CursorPosX,CursorPosY ) ;
}

/************************************************************************/
/*      Clear "BLOCK" from Information area                             */
/************************************************************************/

static void ClearBLOCK()
{
        strcpy( Information+27,"     " ) ;
        Information[32] = ' ' ;
        Locate( 0,0 ) ;
        PrintMessage( Information ) ;
        Locate( CursorPosX,CursorPosY ) ;
}

/************************************************************************/
/*      Get block length                                                */
/************************************************************************/

static int GetBlockLength( max )
int     max ;
{
        int     length ;

        if ( CurrentLine >= BlockTopLine ) {
                length          = CurrentLine - BlockTopLine + 1 ;
                BlockBottomLine = CurrentLine ;
        }
        else {
                length          = BlockTopLine - CurrentLine + 1 ;
                BlockBottomLine = BlockTopLine ;
                BlockTopLine    = CurrentLine ;
        }
        if ( length > max ) {
                Locate( 0,0 ) ;
                PrintMessage( "Block too big. " ) ;
                InputChar() ;
                length = 0 ;
        }
        return ( length ) ;
}

/************************************************************************/
/*      Paste Block                                                     */
/************************************************************************/

extern int PasteBlock()
{
        register unchar *souptr,*desptr ;
        register int     count,line ;

        line = MaximumLine + CutBufLength ;
        if ( CutBufLength > 0 && line < MAXLINE-1 ) {
                souptr      = &TextBuffer[MaximumLine][MAXCOLUM-1] ;
                desptr      = &TextBuffer[line       ][MAXCOLUM-1] ;
                count       = ( MaximumLine-CurrentLine+1 ) * MAXCOLUM ;
                MaximumLine = line ;
                while ( count-- )  *desptr-- = *souptr-- ;
                memcpy( &TextBuffer[CurrentLine][0],CutBuffer,CutBufLength*MAXCOLUM ) ;
                DisplayAfter() ;
                Locate( CursorPosX,CursorPosY ) ;
        }
        return ( InputChar()) ;
}

/************************************************************************/
/*      Delete Block                                                    */
/************************************************************************/

extern int DeleteBlock()
{
        register unchar *souptr,*desptr ;
        register int     count,length ;

        if ( SelectFlag ) {
                SelectFlag = 0 ;
                if (( length = GetBlockLength( CUTLINE )) > 0 ) {
                        memcpy( CutBuffer,&TextBuffer[BlockTopLine][0],length*MAXCOLUM ) ;
                        CutBufLength = length ;
                }
                if ( BlockBottomLine < MaximumLine ) {
                        desptr = &TextBuffer[BlockTopLine     ][0] ;
                        souptr = &TextBuffer[BlockBottomLine+1][0] ;
                        count  = ( MaximumLine - BlockBottomLine ) * MAXCOLUM ;
                        while ( count-- )  *desptr++ = *souptr++ ;
                        MaximumLine -= length ;
                }
                else {
                        desptr = &TextBuffer[BlockTopLine][0] ;
                        for ( count=0 ; count<MAXCOLUM ; count++ ) *desptr++ = ' ' ;
                        MaximumLine -= length-1 ;
                }
                MoveCursorLine( BlockTopLine,CursorPosY-1 ) ;
                ClearBLOCK() ;
        }
        return ( InputChar()) ;
}

/************************************************************************/
/*      Copy Block                                                      */
/************************************************************************/

extern int CopyBlock()
{
        int     length ;

        if ( SelectFlag ) {
                SelectFlag = 0 ;
                if (( length = GetBlockLength( CUTLINE )) > 0 ) {
                        memcpy( CutBuffer,&TextBuffer[BlockTopLine][0],length*MAXCOLUM ) ;
                        CutBufLength = length ;
                }
                ClearBLOCK() ;
        }
        return ( InputChar()) ;
}

/************************************************************************/
/*      Save part of text                                               */
/************************************************************************/

extern int SavePartText()
{

        if ( CutBufLength > 0 ) {
                PutStr( "\033[7m" ) ;
                PutStr( "\033[1;1H\033[KWrite File Name:" ) ;
                if ( InputString( 16,0 ) > 0 ) {
                        PutStr( "\033[1;1H\033[K" ) ;
                        PrintMessage( " Saving Now !!" ) ;
                        if ( SaveCutBuffer( StringBuffer,CutBufLength ) == ERROR ) {
                                PutStr( "\033[1;1H\033[K" ) ;
                                PrintMessage( "File save error." ) ;
                                InputChar() ;
                        }
                }
                PutStr( "\033[27m" ) ;
                PutStr( "\033[1;1H\033[K" ) ;
                PrintMessage( Information ) ;
                Locate( CursorPosX,CursorPosY ) ;
        }
        return ( InputChar()) ;
}
