macro_file cases;

// Originals by Lothar Smidth
// Works now both ways, works nicer, not only u/d/o/case to the right!
// undo not needed!
// ToDo: StreamLining of macros, Macro Flow can go better!
// First Char not done yet!
// Lars Jeurissen

// ToDo: Streamlining, find out to which keys it
// it is assigned, so jou don't have to change it
// in the macro
// Instead of three macros, it can with one macro
// if (parse_str('/CASE=',nparm_str) == 'UPPER') { }

macro UpperCase TRANS         // convert letter to uppercase
  {
    push_undo;
    int lefty = false;
    int temp_insert = insert_mode;
    insert_mode = false;
    if ((key1 == 0) and (key2 == 51)) // change this to the assignd keys
    {
      lefty = true;
      if ((c_col == 1) and (c_line > 1))
      {
        up;
        eol;
      }
      left;
    }
    else
    {
      if ((at_eol) and not(at_eof))
      {
        down;
        goto_col(1);
      }
    }
    text(caps(cur_char));
    if (lefty == TRUE)
      left;
    insert_mode = temp_insert;
    pop_undo;
	}

macro LowerCase TRANS              // convert letter to lowercase, move cursor left
	{
    push_undo;
    int lefty = false;
    int temp_insert = insert_mode;
    insert_mode = false;
    if ((key1 == 253) and (key2 == 115))
    {
      lefty = true;
      if ((c_col == 0) and (c_line > 1))
      {
        up;
        eol;
      }
      left;
    }
    else
    {
      if ((at_eol == 1) and (at_eof != 1))
      {
        down;
        goto_col(1);
      }
    }
    text(lower(cur_char));
    if (lefty == true)
      left;
    insert_mode = temp_insert;
    pop_undo;
	}

macro OtherCase TRANS                   // Convert to other case
	{
    push_undo;
    int lefty = false;
    int temp_insert = insert_mode;
    insert_mode = false;
    if ((key1 == 254) and (key2 == 51))
    {
      lefty = true;
      if ((c_col == 1) and (c_line > 1))
      {
        up;
        eol;
      }
      left;
    }
    else
    {
      if ((at_eol == 1) and (at_eof != 1))
      {
        down;
        goto_col(1);
      }
    }
    if  ((cur_char >= "A") && (cur_char <= "Z"))  {
      text(lower(cur_char) );
    } else {
      if  ((cur_char >= "a") && (cur_char <= "z"))  {
        text(caps(cur_char));
      } else {
        text((cur_char));
      }
    }
    if (lefty == true)
      left;
    insert_mode = temp_insert;
    pop_undo;
	}

macro_file bubbles;

macro BubbleUp        // BubbleUp :  move cursor line up
 {
    int temp_refresh = refresh;
    refresh = false;
    push_undo;
    if (block_stat) {
      rm("BubbleBlockUp");

    } else {
      rm("BubbleLineUp");
    }
    pop_undo;
    refresh = temp_refresh;
  }

macro BubbleLineUp  {
    if (c_line > 1)
    {
      str a[2048] = get_line;
      up;
      str b[2048] = get_line;
      put_line(a);
      down;
      put_line(b);
      up;
    }
}

                              // Written by: Lars Jeurissen
// 12-13-93 07:33am LS simplified and corrected some logic glitches.
// 12-13-93 04:10pm LS made fit for all block types.
// BubbleBlockUp: move block 1 line up
macro BubbleBlockUp
  {
    int temp_insert = insert_mode;
    insert_mode = true;
    Goto_Col( Block_Col1 );
    up;
    Goto_Line( Block_Line1 - 1 );
    move_block;
    insert_mode = temp_insert;
  }




macro BubbleDown              // BubbleDown:  move cursor line down
  {
    int temp_refresh = refresh;
    refresh = false;
    push_undo;
    if (block_stat) {         // better : if cursor in block ...
      rm("BubbleBlockDown");
    } else {
      rm("BubbleLineDown");
    }
    pop_undo;
    refresh = temp_refresh;
  }


macro BubbleLineDown
  {
      str a[2048] = get_line;
      down;
      str b[2048] = get_line;
      put_line(a);
      up;
      put_line(b);
      down;
  }

// Written by: Lars Jeurissen
// 12-13-93 04:10pm LS made fit for all block types.
// simplified logic
// BubbleBlockDown: move block 1 line down
macro BubbleBlockDown
  {
    int temp_insert = insert_mode;
    insert_mode = true;
    int dest = block_line2 + 1;
    Goto_Col( Block_Col1 );
    if (block_stat == 1)  {
      ++dest;  }
    if (block_stat == 2)  {
      dest = block_line1 + 1;  }
    down;
    goto_line(dest);
    move_block;
    goto_line(block_line1);
    insert_mode = temp_insert;
  }
                              // Written by: Lars Jeurissen
macro Bubbleleft              // BubbleUp :  move block to the left
	{
  int flag = block_stat;
  str tmpline;
  int linelen;

  if (flag == 0)
    make_message('No Block Marked!');
  else
    {
      push_undo;
      tmpline = Get_Line;
      linelen = length(tmpline);
      goto_col(block_col1);
      if ((c_col >= linelen) and (at_eof == false))
      {
        down;
        Goto_Col(1);
      }
      left;
      if (flag == 2)
        column_move_style;
      move_block;
      pop_undo;
    }
	}
                              // Written by: Lars Jeurissen
macro BubbleRight             // BubbleRight:  move block to the right
	{
  int flag = block_stat;

  if (flag == 0)
    make_message('No Block Marked!');
  else
    {
      push_undo;
      goto_col(block_col2);
      Right; Right;
      if (flag == 2)
        column_move_style;
      move_block;
      pop_undo;
    }
  }
                              // Written by: Lars Jeurissen
macro BubbleBlockRight  {     // Bubble block right
  int t_refresh=refresh;
  push_undo;
  refresh=false;

  if (!Block_Stat)
  {
    rm('MEUTIL2^MARKBLCK');
    rm('MEUTIL2^INDBLK ');
    Right;
    Right;
    rm('MEUTIL2^BLOCKOFF');
  }  else  {

    rm('MEUTIL2^INDBLK');
  }
  refresh=t_refresh;
  pop_undo;
}
                              // Written by: Lars Jeurissen
macro BubbleBlockLeft  {      // Indent block left
  int t_refresh=refresh;
  push_undo;
    refresh=false;

  if (!Block_Stat)
  {
    rm('MEUTIL2^MARKBLCK');
    rm('MEUTIL2^UNDBLK');
    Left;
    Left;
    rm('MEUTIL2^BLOCKOFF');
  }  else  {

    rm('MEUTIL2^UNDBLK');
  }
  refresh=t_refresh;
  pop_undo;
}

macro CommentBlock            // fill column block with next key
  {
    int old_col_move_style = column_move_style;

    push_undo;

    Set_Global_Int("!SmartBlock", C_Col);
		COL_BLOCK_BEGIN;
		Make_Message('Columnar block marking on.  Press ' + Global_Str('!BM_KEY15') + ' to stop.');

    if ( block_stat == 2      /* column blocks */ )
    {
      int temp_refresh = refresh;
      int temp_insert = insert_mode;

      refresh = false;
      insert_mode = false;
      mark_pos;

      make_message( 'press character to fill block with (ESC aborts) :' );
      read_key;
      make_message( '' );
      if (key1 != 27 )                  /* allow escape */
      {
        if (marking)
        {
          block_end;
        }
        rm('TopBlock');
        for  (int i= block_line1; i <= block_line2; ++i)
        {
          mark_pos;
          for  (int j= block_col1; j<=block_col2; ++j)
          {
            text(char(key1));
              }
          goto_mark;
          down;
        }
      }
      else
      {
        make_message( 'fill aborted' );
      }
      goto_mark;
      insert_mode = temp_insert;
      refresh = temp_refresh;
    }
    else
    {
      make_message( 'FillBlock: no column block. Use '
                    + global_str ('!BM_KEY16')
                    + ' to define one.'  );
    }
    pop_undo;
    column_move_style = old_col_move_style;
  }

macro_file edmac;

macro EditMacro               // 12-07-92 02:51pm LS
	{
		int Inq_Int,
				T_Int,
				temp_refresh;

    str MacroFile[64],
		    MacroName[32],
				Inq_Str[26];


    Make_Message('press another key to edit its macro definition');
		READ_KEY;
		Make_Message('');

		temp_refresh = refresh;
		refresh = false;
		Inq_Int = Inq_Key(Key1,Key2,0,Inq_Str);
		if (Inq_Int == 1)	    						// pressed key is a macro

		{																	// Strip off parameter list if present
			T_Int = XPos(' ',Inq_Str,1);
			if (T_Int)
			{
				Inq_Str = Str_Del(Inq_Str,T_Int,25);
			}

			T_Int = XPos('^',Inq_Str,1);
			if (T_Int)											// string contains a caret, followed by
			{																// filename
				MacroFile = me_path + 'SRC\'+ Str_Del(Inq_Str,T_Int,25)+'.S';
		    MacroName = Str_Del(Inq_Str,1,T_Int);
			}
			else                            // no caret=no filename. try MESYS.S
			{
				Make_Message (Inq_Str);
				MacroFile = me_path + 'SRC\MESYS.S';
		    MacroName = Str_Del(Inq_Str,1,T_Int);

			}
		  Return_Str = MacroFile;
		  RM('LDFILES /NR=1 /CW=2 /LC=1' );
			tof;
			Ignore_Case = TRUE;

/* this assumes regular expressions = ON
   for the % sign (string at start of line )  */

      search_fwd('%macro ' + MacroName,0);

		}
		else															// key is not a macro
		{
			 		 Make_Message('function ' + Inq_Str + str(Inq_Int)
					 +  '; not a macro - no source available');
		}
		refresh = temp_refresh;
	}

Macro_File LJSYS;

// FileUnderCursor                ( -- )
// DosExecuteLine                 ( -- )

macro FileUnderCursor         // open
	{
		int temp_refresh = refresh;
		refresh = false;
		mark_pos;
		right;
		word_left;

		Return_str = get_word(' |9|255');
		goto_mark;
		refresh = temp_refresh;
		RM( "LDFILES /CW=2 /LC=1 /NC=1" );
	}

macro DosExecuteLine          // DosExecute :  execute line under cursor
	{
		rest_dos_screen;
		Return_Str = get_line;
	  RM("exec");
		while(!check_key);
		new_screen;
	}

macro_file DosShell


macro DOSWINDOW TRANS2 {
/*******************************************************************************
                                MULTI-EDIT MACRO

Name: DOSWINDOW

Description:  Run DOS from EDIT mode, restoring the original DOS screen.

*******************************************************************************/
  str CMD_Parm[2], Batch_Parm[8];
  int tr;

  tr = Refresh;
  Refresh = False;
  if ( '' == (Return_Str = Global_Str('@SHELL_TO_DOS_CMD')) ) {
    R_AX = $D44D; R_BX = 0; INTR(0x2F);
    if ( R_AX == $44DD ) {
      CMD_Parm = ''; Batch_Parm = '__4DOS__';
    } else {
      CMD_Parm = '/C'; Batch_Parm = '';
    }
  }
  rm('MEUTIL1^EXEC /SWAP=0/MEM=' + Str(Swap_Mem) + '/SCREEN=3/T=Buggy Where/CMDLN=1');
  Refresh = tr;

  /* in case that the current window is trashed, so always redraw it */

  Redraw;
}

macro SEARCHLIB {
/*******************************************************************************
																MULTI-EDIT MACRO

Name: SEARCHLIB

Description:  Library File Search, if the cursor is on a word, the macro search
              for the beginning of that word, and wil search for that word in
              your LIB directory, p.e. %LIB = C:\CF\LIB, it wil search trough
              that directory.

Parameters:   /FS    FileSpecifier         ( /FS=*.* )
              /SW    Search Switches       ( /SW=IXD )
              /DL    Get Word Delimiters   ( /SW= |9|255 )
              /S1    Search Expression 1   ( /S1={%[UHL]: )
              /N     Skips directly to the ( /N=. )
                     filename list, using
                     the last set of files
                     found by MEFIND.

*******************************************************************************/
    str  search_str[80] = '',
         switches_str[10] = '',
         old_switches_str[10] = '',
         delimiter_str[15] = '',
         filespec[80] = '',
         libpath[80] = '',
         searchexp_str1[25] = '',
         searchexp_str2[25] = '',
         sstr[80] = '',
         Find_Name[80];
    int  t_win,
         nl,
         jx,
         y1,
         list_window,
         already_loaded,
         result,
         old_col;

    /* Keep old switches, so we can restore them */

    old_switches_str = Global_Str('SWITCHES');

    /* Parse FileSpecifier
       if not specified, we will use '*.*' */

    filespec = parse_str('/FS=', mparm_str );
    if (( filespec == "" )) {
      filespec = "*.*";
    }

    /* Parse Search Switches
       if not specified, we will use 'RCSFO' */

    switches_str = parse_str('/SW=', mparm_str );
    if (( switches_str == "" )) {
      switches_str = "RCSFO";
    }

    /* Parse Get_Word delimiters
       if not specified, we will use ' ''|9|255' */

    delimiter_str = parse_str('/DL=', mparm_str );
    if (( delimiter_str == "" )) {
      delimiter_str = ' ''|9|255';
    }

    /* Parse Search Expression 1 and 2
       if not specified, then only string is searched for */

    searchexp_str1 = parse_str('/S1=', mparm_str );
    searchexp_str2 = parse_str('/S2=', mparm_str );

    /* Get current window ID */

    t_win = window_id;

    /* Increase macro speed, don't forget to put it on */
    refresh = 0;

    /* Keep current column for later use */

    old_col = C_COL;

    /* It is not necesarry to place cursor at begin of word, we wil get
       begin of word ourself */

    if ((CUR_CHAR == ' ')) {
      /* We Don't stand on a word */
        rm('MEERROR^MessageBox /M=No word under cursor.');
      GoTo exitxx;
    }

    /* If we stand on column 1 and the cur_char != ' ', means that we must
       stand at begin of word */

    if (old_col != 1) {
      while ( (CUR_CHAR != ' ') AND (C_COL > 1) ) {
        LEFT;
      }
      if (CUR_CHAR == ' ') {
        RIGHT;
      }
    }

    /* Get search word delemited with user defined /DL= */

    search_str = Get_Word(delimiter_str);

    /* Restore old cursor position */

    GOTO_COL(old_col);

    /* Get Forth LIB Envirionment
       We use the in %LIB defined directory as a search path,
       if %LIB is not defined we use current directory as path  */

    libpath = GET_ENVIRONMENT('LIB');

    /* Now Search whole word in %LIB */

    /* return code */

    result = 0;

    /* If the USER_ID is 3 characters in length, it will make MEFIND.TMP be
       xxxMEFIN.TMP due to the 8 character limit. */

    Find_Name = me_path + Copy(user_id + 'LIBFND',1,8) + '.TMP';

    /* Last findlist needed, find_file has a own name,
       so it couldn't  overwrite the normal filesearch file */

		if(  xpos('/N', caps(mparm_str), 1 )  ) {
			if(  NOT(switch_file(Find_Name))  ) {
				switch_window( window_count );
				create_window;
				window_attr = $80;
				load_file(find_name);
				if(  error_level == 0  ) {
					goto load_find_file;
				}
				file_name = find_name;
				rm('MEERROR^MessageBox /M=No matched file available.');
			} else {
				goto load_find_file;
			}
		}

    /* We want to search */

    set_global_str('FSEARCH_PATH',libpath);
    set_Global_Str('FSWITCHES', switches_str);

		if(  return_int  ) {
			working;
			y1 = 5;
			if(  switch_file(Find_Name)  ) {
				erase_window;
			} else {
				switch_window( window_count );
				create_window;
				window_attr = $80;
			}
			file_name = find_name;

      /* user provided search expression */

      Return_Str = searchexp_str1 + search_str + searchexp_str2;

      /* Search in directories and search files in memory */
      RM('FILESRCH /SD=1/SM=1/PATH='+filespec+'/ROOT='+libpath);

      set_Global_Str('SEARCH_STR', searchexp_str1 + search_str + searchexp_str2);
      set_global_str('SWITCHES', switches_str);

      SET_GLOBAL_INT('SEARCH_MODE',0);

			if(  (error_level != 0)  ) {
				goto exitx;
			}
			if(  (return_int == -1)  ) {
        sstr = 'Library search aborted by user.';
        rm('MEERROR^MessageBox /B=2/T=Library-File Search Error/M=' + sstr );
				goto exitx;
			}
			tof;

load_find_file:
no_create:
			window_attr = window_attr | $81;  /* make it hidden and invisible */
			if(  at_eof  ) {
				eof;
				goto_col(1);
				if(  at_eof  ) {
					RM('MEERROR^MESSAGEBOX /B=2/T=NO MATCHED FILES FOUND');
					goto exitx;
				}
			}
			if(  file_changed  ) {
				save_file;
			}
			goto_col(1);
			list_window = window_id;
       set_global_str('IPARM_1','/C=1/TP=15/L=1/T=Select Library file to view:/DC=1/WIN=' + str(cur_window));
							 	RM('USERIN^DATA_IN /A=2/POSG=@MFSPOS@/#=1/T=MATCHED FILES/H=SEARCHLIST');
				window_attr = window_attr | $81;  /* make it hidden and invisible */
				if(  return_int != 1  ) {
					switch_win_id(t_win);
					goto exit;
				}
REPLACE_LOAD:
			already_loaded = 0;
			result = 1;
			Goto_Col(1);
			jx = insert_mode;
			insert_mode = FALSE;
			text('|175');
			insert_mode = jx;
			file_changed = false;
			return_str = shorten_str(get_word(' '));
			forward_till(':');
			right;
			sstr = get_word(' ');
			val(nl,sstr);
			set_global_int('@FLAST_CHOICE', c_line);
			forward_till_not(' ');
			return_str = fexpand( get_word('') + return_str);
			if(  xpos('|254', return_str,1) != 0  ) {
				goto exitx;
			}
			if(  switch_file( return_str )  ) {
				already_loaded = 1;
				window_attr = window_attr & $FE;
				make_message( return_str + ' already loaded.');
        tof;
				goto no_load;
			}
      switch_win_id( t_win );
      RM('LdFiles /CW=2');

			if(  error_level == 0  ) {
				Make_Message('"' + File_Name + '" loaded.');
no_load:
				down; down; down; down;
				goto_line( nl );
				if(  format_stat  ) {
					up;
				}
				goto_col( 1 );
				left;
        search_fwd(global_str('SEARCH_STR'),0);
			} else {
				switch_win_id(t_win);
			}
		}
exit:
	if(  error_level != 0  ) {
exitx:
		switch_win_id(t_win);
	}
exitxx:
  /* Restore old SWITCHES */

  set_global_str('SWITCHES', old_switches_str);

  return_int = result;
  refresh = 1;
  update_status_line;

}



