/*

CLASS {AL4_form|s_Java_Android},
NATIVE, UNTESTED, BITWISE :
IMPORT: {Screen}, {Form}, {Control}, {Combo}, {Font}, {Geometry} .
IMPORT: {Edit}, {Listbox}, {Icon}, {Localize_str}, {Dialog} .
IMPORT, ANYWAY: {Log_html}, {Long_operation} .
IMPORT: {Sorting} .

NATIVE: "import android.graphics.*;" .
NATIVE: "import android.view.*;" .
NATIVE: "import android.widget.*;" .
NATIVE: "import android.util.*;" .
NATIVE: "import java.util.Calendar;" .
NATIVE: "import android.os.*;" .


*/
import java.util.ArrayList;
import java.util.concurrent.CopyOnWriteArrayList;
import android.widget.*;
import android.widget.TextView.*;
import android.view.inputmethod.*;
import android.view.*;
import android.view.ViewGroup.*;
import android.view.MenuItem.*;
import android.view.GestureDetector.*;
import android.graphics.*;
import android.graphics.drawable.*;
import android.content.*;
import android.app.*;
import android.util.*;
import android.text.method.*;
import android.os.*;
import java.lang.reflect.*;

import java.util.Timer;
import java.util.TimerTask;

import java.util.Calendar;
import java.util.GregorianCalendar;

import android.content.res.Resources;
import android.content.res.TypedArray;
import android.text.*;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.*;

import java.io.*;

public class AL4_form {
	public static MainActivity context_activity;
    LinearLayout Title_line;
    String Caption = "";
    boolean Disable_timers;
    
    public static boolean Application_terminated;

    public static class Descriptor {
        Object Jvc; // Java visual component (including Frame) or other Java Object
        Ref_obj Ref; // AL4 visual control or column or form or null
        int Next_free;
    }

	public static CopyOnWriteArrayList<Descriptor> All_descr = 
        new CopyOnWriteArrayList<Descriptor>();
	public static int Free_position_in_descr_list = -1;

	public static int Alloc_descriptor(Object Jobj, Ref_obj Robj)
	{
		if (All_descr.size() == 0)
			All_descr.add(new Descriptor());
        Descriptor D = null;
        int Result = All_descr.size();
		if (Free_position_in_descr_list >= 0) {
			Result = Free_position_in_descr_list;
			Free_position_in_descr_list = (int)All_descr.get(Result).Next_free;
			D = All_descr.get(Result);
		}
        else {
            D = new Descriptor();
            All_descr.add(D);
        }
        D.Jvc = Jobj;
        D.Ref = Robj;
        D.Next_free = -999;
		return Result;
	}

	public static void ReleaseDescriptor(int idx)
	{
		if (idx <= 0) return;
        
        //AL4_system.WriteLine("RELEASE " + idx);
        
        Descriptor D = All_descr.get(idx);
        D.Jvc = null;
        D.Ref = null;
        D.Next_free = Free_position_in_descr_list;
		Free_position_in_descr_list = idx;
	}
    
    public static Ref_obj Get_control_ref(Object C) {
        return Get_control_ref(C, false);
    }

    public static Ref_obj Get_control_ref(Object C, boolean Allow_null)
    {
        while (C != null) {
            for (int i = 0; i < All_descr.size(); i++)
            {
                Descriptor D = All_descr.get(i);
                if (D == null) continue;
                if (D.Jvc == C) return D.Ref;
            }
            if (!(C instanceof View)) break;
            C = ((View)C).getParent();
        }
        //if (!Allow_null) {
        //    //AL4_system.WriteLine("Get_control_ref: NULL for " + C);
        //    //Thread.dumpStack();
        //}
        return null;
    }
    
	/*
	
	FUN wwa|_where_we_are ==> STR, PUBLIC, NATIVE : @ 
	"RESULT = AL4_form.wwa();" .
	
	*/
	public static long last_wwa_time;
	
	public static String wwa() {
		String RESULT = Looper.getMainLooper() == Looper.myLooper()
			   ? "@" : "!";
		long u = SystemClock.uptimeMillis();
		if (u - last_wwa_time > 10)
			RESULT = "" + (u - last_wwa_time) + RESULT;
		last_wwa_time = u;
		return RESULT;
	}
	/*
    

	// Called when the {Screen} object is created. Used to setup global things
	//------------------------------------------------------------------------
	
	FUN Screen_created(
	{Screen} S|creen_object_dummy), NATIVE : @
    	"	if (AL4_form.Screen_object_ref_== null)	{"
    	"		AL4_form.Screen_object_ref_ = X_S;"
    	"		AL4_form.Screen_object_ref_.Count += 2;"
    	"	}"
    	"	else {"
		"	    AL4_form.Screen_object_ref_ = Object_assign_weak("
		"		    AL4_form.Screen_object_ref_, X_S.Obj);"
    	"	}"
		"   AL4_form.Do_Screen_created(X_S);" .
		
	FUN Screen_destroyed({Screen} Screen|_object_dummy) : .
	*/
	public static void Do_Screen_created(Ref_obj X_Screen)
	{
        AL4_form.Screen_handler sh = new AL4_form.Screen_handler(X_Screen);
        AL4_system.long_operation_handlers.add(sh);
	}
	
	public static Ref_obj Screen_object_ref_;
	public static boolean App_running;
	/*
	// running application until it is terminated
	//-------------------------------------------
	
	FUN Run_screen_forms({Screen} Screen|_object), NATIVE :
        INT h|andle_main_form = Screen.Main_form_.Handle
        NATIVE @
        "	 AL4_form.main_form_handle = X_h;"
        "	 AL4_form.App_running = true;"
		"    AL4_form.Do_Application_Run(X_h);"
        "	 AL4_form.App_running = false;" .
		
    FUN Application_terminated ==> BOOL, NATIVE : @
	"RESULT = !AL4_form.App_running;" .
        
	FUN Get_screen|_object ==> {Screen}, NATIVE : @
		"	if (AL4_form.Screen_object_ref_ != null)"
		"		RESULT = AL4_form.Screen_object_ref_;" .
	
    FUN Set_main_form_handle(
    INT H|andle_of_main_form), NATIVE :
		"	AL4_form.Main_form_handle = X_H;" .
		
	FUN Ticks_from_power_up ==> INT, NATIVE : @
		"	Calendar rightNow = Calendar.getInstance();"
		"	RESULT = (int)rightNow.getTimeInMillis();" .
	
	*/
	public static void report(Exception ex) {
		AL4_system.WriteLine("*** Exception *** " + ex + 
		"\n--------------------------------------------------------------\n" +
		stack_trace(ex) + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
	}
	
	public static int Main_form_handle;
	
	public static void Do_Application_Run(int H) throws Exception
	{
        AL4_form form = null;
		if (H > 0) {
                C_Form F = (C_Form)AL4_form.All_descr.get(H).Ref.Obj;
                
                C_Screen S = (C_Screen)F.F_Screen_.Obj;
                //$DEBUG$:
                //AL4_system.WriteLine("do_application_run, Screen=" + S + 
                //   " Screen.F_Main_form_.Obj:" +
                //    S.F_Main_form_.Obj + ", F=" + F); 
                    
            
            form = (AL4_form)AL4_form.All_descr.get(H).Jvc;
            if (!form.Hidden) {
            	activate_form(form);
                
				if (operation_started(F, 9, F.hard_link)) {
				//-----------------------------------------
                    \\new Thread(
                    \\    new Runnable() {
                    \\        public void run() {
                                  try {
                                      try {
                                          try {
                                              F.M_shown();
                                          }
                                          finally {
                                              operation_ended(F, 9);
                                          }
                                      }
                                      catch (AL4StopException e) { }
                                  }
                                  catch (Exception ex) { report(ex); }
                    \\        }
                    \\    }
                    \\).start();
				//-----------------------------------------
				}
            }
            //! in Java, there is not necessary to call message handling loop,
            //! but we must provide time life for Screen object until Application
            //! terminated:
            
            S.hard_link.Count += 2;
        }
	}

    public final static int LOGPIXELSX = 96;
	public static float pixels_per_inch = 0;

	/*
	
	FUN Set_form_application_button(
	INT H|andle_of_form, BOOL Value|_set) : .
	
	FUN Is_mobile_screen ==> BOOL := TRUE .
	
	//---------- points --> pixels
	
	FUN Points|_convert_to_pixels(REAL P|oints_value) ==> INT,
		NATIVE :
		"    RESULT = AL4_form.Points(X_P);" .
	*/
	public static void provide_pixels_per_inch() {
		if (pixels_per_inch == 0) {
			Display display = context_activity.getWindowManager().getDefaultDisplay();
			DisplayMetrics metrics = new DisplayMetrics();
			display.getMetrics(metrics);
			
            pixels_per_inch = metrics.densityDpi;
		}
	}
	
	public static float Points_float(double pts) {
		provide_pixels_per_inch();
		return (float)(pixels_per_inch / 96.0 * pts);
	}

	public static int Points(double pts) {
		return (int)Math.rint(Points_float(pts));
	}

	/*
	//---------- pixels --> points
	
	FUN Pixels|_convert_to_points(REAL P|ixels_value) ==> REAL,
	NATIVE :
		"    RESULT = AL4_form.Pixels(X_P);" .
	*/
	public static double Pixels(double pix) {
		provide_pixels_per_inch();
		return pix * 96.0 / pixels_per_inch;
	}
    
    /*
    
    FUN List_screen_monitors(INT H|andle_form_dummy), NATIVE :
        "    AL4_form.Do_list_monitors();" .
    */
    public static CopyOnWriteArrayList<Rect> Monitors = 
        new CopyOnWriteArrayList<Rect>();
    
    public static void Do_list_monitors() {
        Monitors.clear();
        DisplayMetrics dM = new DisplayMetrics();
        context_activity.getWindowManager().getDefaultDisplay().getMetrics(dM);
        Monitors.add(new Rect(0, 0, dM.widthPixels, dM.heightPixels));
        //! suppose that in the Andoid there	\ полагаем, что в Android есть
        //! is one monitor always			    \ только один монитор всегда
    }

	/*
	
	FUNCTION Fake_screen_monitor(
	INT H|andle_form_dummy,
	{Geometry}.{rect} Bounds|_of_adding_mointor,
	BOOL Clear_before|_adding)
		: 
		do_Fake_screen_monitor(Bounds.Loc.X, Bounds.Loc.Y,
			Bounds.Width, Bounds.Height, Clear_before)
		.
   	FUN do_Fake_screen_monitor(
   	REAL X|_points, REAL Y|_points,
   	REAL W|idth_points, REAL H|eight_points, BOOL Clear_before),
   		NATIVE : @
        "if (X_Clear_before) AL4_form.Monitors.clear();"
        "AL4_form.Monitors.add("
            "new Rect("
                "AL4_form.Points(X_X),"
                "AL4_form.Points(X_Y),"
                "AL4_form.Points(X_W),"
                "AL4_form.Points(X_H)));" .
                
	FUN Count_screen_monitors(
	INT H|andle_form_dummy) ==> INT, NATIVE : @
	    "    RESULT = AL4_form.Monitors.size();" 
	    "	 if (RESULT == 0) {"
	    "		AL4_form.Do_list_monitors();"
	    "    	RESULT = AL4_form.Monitors.size();" 
	    "	 }" .
                

	FUNCTION Get_screen_monitor(
	INT H|andle_form_dummy,
	INT Index|_of_monitor) ==> {rect}
	:= {rect}(Loc = Pt(do_Get_screen_monitor(Index, "X"),
					   do_Get_screen_monitor(Index, "Y")),
			  Width = do_Get_screen_monitor(Index, "W"),
			  Height = do_Get_screen_monitor(Index, "H"))
	.
		
	FUN do_Get_screen_monitor(
		INT I|ndex_monitor, STR Coord|inate) ==> REAL,
		NATIVE : @
       "if (X_I < 0 || X_I >= AL4_form.Monitors.size()) return 0;"
       "switch (X_Coord.charAt(0)) {"
       "	case 'X': "
       "	  return AL4_form.Pixels(AL4_form.Monitors.get(X_I).left);"
       "	case 'Y': "
       "	  return AL4_form.Pixels(AL4_form.Monitors.get(X_I).top);"
       "	case 'W': "
       "	  return AL4_form.Pixels(AL4_form.Monitors.get(X_I).width());"
       "	case 'H': "
       "	  return AL4_form.Pixels(AL4_form.Monitors.get(X_I).height());"
       "}" .
			
	FUNCTION Screen_bounds(INT H|andle_form) ==> {rect}
		:
		FOR i IN [0 TO Count_screen_monitors(H)-1] :
		    CASE i == 0 ? RESULT = Get_screen_monitor(H, 0)
		    ELSE {rect} m|onitor_i = Get_screen_monitor(H, i)
		    	 CASE RESULT.Loc.X > m.Loc.X ? RESULT.Loc.X = m.Loc.X ; 
		    	 CASE RESULT.Loc.Y > m.Loc.Y ? RESULT.Loc.Y = m.Loc.Y ;
		    	 CASE RESULT.Right < m.Right ?
		    	      RESULT.Width = m.Right - m.Left ;
		    	 CASE RESULT.Bottom < m.Bottom ?
		    	      RESULT.Height = m.Bottom - m.Top ;
		    ;
		; .
		
	FUN Set_forms_autoscroll(BOOL A|utoscroll_forms) : .
		    
	// create form
	//------------------------------------------------------------------
	
	FUN Form_create|_create_form(
	{Form} F|orm_object) ==> INT, NATIVE :
		    //DEBUG: << "Form_create call_________"#NL ;
		NATIVE @
		"    RESULT = AL4_form.Do_Form_create(X_F);" 
		//''	AL4_system.WriteLine("Form_create() ==> RESULT=" + RESULT);''
		.
		
	FUN Form_set_icon(
		{Form} F|orm_object|DUMMY_not_relevant_for_Android, 
		INT Bitmap_h|andle_containing_icon|DUMMY) : .
		
	*/
	
	public static void Prepare_main_menu(Menu menu) {
	
//////////////////////////////////////////////////////////////////
//AL4_system.WriteLine("************ Prepare_main_menu called!!!");
//try {
//C_Log_html.M_Log_colored(0xff000000, "************ Prepare_main_menu called!!!\n");
//////////////////////////////////////////////////////////////////

		menu.clear();
		
		View anchor_view = context_activity.HView; 
		if (Active_form != null) {
			anchor_view = Active_form.TV_top;
		}
		PopupMenu pm = new PopupMenu(context_activity, anchor_view, Gravity.TOP);
            
		if (Forms_shown.size() > 1) {
			for (int i = 0; i < Forms_shown.size(); i++) {
				AL4_form form = Forms_shown.get(i); 
				String m_caption = form.Caption;
				if (m_caption == "") m_caption = "[" + (i+1) + "]";
				MenuItem form_item = pm.getMenu().add(m_caption);
				if (form == Active_form) form_item.setEnabled(false);
				
				form_item.setOnMenuItemClickListener(
					new OnMenuItemClickListener(){
					@Override
					public boolean onMenuItemClick(MenuItem item) {
						activate_form(form);
						return true;
					}
				});
			}
		}
		MenuItem exit_item = pm.getMenu().add("Exit");
		exit_item.setOnMenuItemClickListener(
			new OnMenuItemClickListener(){
			@Override
			public boolean onMenuItemClick(MenuItem item) {
				for (int i = 0; i < Forms_shown.size(); i++) {
					AL4_form form = Forms_shown.get(i);
					if (form.Handle == main_form_handle) {
						event_form_closed(main_form_handle, true);
						break;
					}
				} 
				do_exit();
				return true;
			}
		});
		
		
		Handler h = new Handler();
		h.postDelayed(new Runnable() {
			public void run() {
				pm.show();
			}
		}, 100);
		
	}
	
	public static void do_exit() {
        Forms_shown.clear();
        try {
        	//context_activity.finishAndRemoveTask(); -- crashing on Android 4.4.4
        	context_activity.finish();
        }
        catch (Exception ex) { report(ex); }
	}
	
	public static void Back_pressed() {
		//! IMPORTANT! we must return here as fast as possible otherwise the
		//! Android OS is killing our program thinking that it is not 
		//! repsponding too long time in reflect to the BACK button pressed.
		//! So, we just create a thread and run our procedure in it, immediately
		//! returning the control.
        run_on_background_thread(new Callable<Void>(){
            @Override public Void call() {
                try {
//try { AL4_system.WriteLine("\nBack pressed" +
//(Looper.getMainLooper() == Looper.myLooper() ? "@" : "!") +
//"\n" + C_AL4_form.M_get_system_stack()  +
//", Active_form=" + Active_form +
//" Pass_dialog_result_to=" + Active_form.Pass_dialog_result_to); } catch(Exception x){}
					try {
						//! IMPORTANT! But the task want to run must always run
						//! on the main (UI) thread. So:
				        run_on_ui_thread(false, new Callable<Void>(){
				            @Override public Void call() {
				                try {
//?{Dialog}
									if (Active_form != null 
									&& Active_form.Pass_dialog_result_to != null
									) {
										((C_Dialog)Active_form.AL4Object).M_ready("");
//AL4_system.WriteLine("\nreturn; Active_form=" + Active_form + " " +
//(Active_form != null ? Active_form.a_content.getVisibility() == View.VISIBLE
//: "form is null") + "\n");
										return null;
									}
//AL4_system.WriteLine("\nBackMainActivity.main_activity.moveTaskToBack(true);");
									MainActivity.main_activity.moveTaskToBack(true);
//.
				                }
				                catch (Exception ex2) { report(ex2); }
				                return null;
				            }
				        });
						
					}
					catch (Exception ex) { report(ex); }
                }
                catch(Exception ex) { report(ex); }
                return null;
            }
        });	
	}
	
	public static String stack_trace(Exception ex) {
		StringBuilder strace = new StringBuilder();
			    for (StackTraceElement se : ex.getStackTrace())
			    	strace.append(se.toString() + '\n');
		return strace.toString();
	}
	
	/*
	
	FUN get_system_stack ==> STR, NATIVE, PUBLIC, CALLBACK : @
	"	try {"
	"	throw new Exception();"
	"}  catch(Exception ex) {"
	"	RESULT = AL4_form.stack_trace(ex);"
	"}"
	.
	
	
	FUN out_system_stack, NATIVE, PUBLIC : @
	"	try {"
	"	throw new Exception();"
	"}  catch(Exception ex) {"
	''	AL4_system.WriteLine(AL4_form.stack_trace(ex));''
    //''	AL4_system.WriteLine("\n2:\n" + AL4_form.stack_trace(ex));''
    //''	AL4_system.WriteLine("\n3:\n" + AL4_form.stack_trace(ex));''
    //''	AL4_system.WriteLine("\n4:\n" + AL4_form.stack_trace(ex));''
	"}" .
		    
	FUNCTION do_long_operation(
	{Form} Caller|_form,
	{Long_operation} Exist|ing_long_operation) ==> {Long_operation} RESULT
	|created_new, NEW, NATIVE, PUBLIC :
	//DEBUG: << "do_long_operation"#NL ;
	NATIVE @
	//"RESULT = AL4_form.call_do_long_operation(X_Caller, X_Exist);" 
	.
	*/
	public static Ref_obj call_do_long_operation(Ref_obj X_Caller, Ref_obj X_Exist) 
		throws Exception {
//?{Long_operation}
//AL4_system.WriteLine("do_long_operation:1");
        Callable<Ref_obj> callable = new Callable<Ref_obj>() {
            @Override
            public Ref_obj call() throws Exception {
               try {
//AL4_system.WriteLine("calling C_Long_operation.M_do_long_operation_synchronously");
                    Ref_obj result = C_Long_operation.M_do_long_operation_synchronously(
                    	X_Caller, X_Exist);
//AL4_system.WriteLine("result=" + result);
					return result;
               }
               catch (Exception ex2) { report(ex2); }
//AL4_system.WriteLine("calling M_do_long_operation_synchronously ==> null");
               return null;
            }
        };
//AL4_system.WriteLine("do_long_operation:2");
        FutureTask<Ref_obj> task = new FutureTask<>(callable);
//AL4_system.WriteLine("do_long_operation:3");
        AL4_form.context_activity.runOnUiThread(task);
//AL4_system.WriteLine("do_long_operation:4 then get");
        Ref_obj RESULT = task.get();
//AL4_system.WriteLine("do_long_operation:5");
        if (RESULT == null) RESULT = X_Exist;
//AL4_system.WriteLine("do_long_operation:6");
        return RESULT;
//.
	}
	
	
	public static ArrayList<AL4_form> Forms_shown = new ArrayList<AL4_form>();
	public static AL4_form Active_form = null;
	
	public static void activate_form(AL4_form form) {
//AL4_system.WriteLine("form -- activate " + form);
		for (int i = 0; i < Forms_shown.size(); i++) {
			AL4_form f = Forms_shown.get(i);
			if (f != form) f.a_content.setVisibility(View.GONE);
		}
		form.Hidden = false;
		form.a_content.setVisibility(View.VISIBLE);
		if (Forms_shown.indexOf(form) < 0)
			Forms_shown.add(form);
		Active_form = form;
//AL4_system.WriteLine("set context_activity Caption to <" + form.Caption + ">");
		context_activity.setTitle(form.Caption);
	}
	
	//[diagram:Aligning.dia] 
	TextView TV_top;
    LinearLayout a_content;
    VScrollView v_content;
    HScrollView h_content;
    public LinearLayout Form = null;
    public LinearLayout Pane_top = null;
    public LinearLayout Pane_middle = null;
    public LinearLayout Pane_bottom = null;
    public LinearLayout Pane_left = null;
    public LinearLayout Pane_right = null;
    public LinearLayout Pane_client = null;
    int Handle;
    
    boolean Dont_touch;
    
	public static int Do_Form_create(Ref_obj X_F) throws Exception
	{
        return get_property_int(new Callable<Integer>(){
            @Override public Integer call() {
      
              try {
				  int Result = 0;
				  try {
				  //C_Log_html.M_Log_colored(0,"Do_Form_create");
				  //--------------------------------------------------------
				  AL4_form form = new AL4_form(X_F);
			      Result = Alloc_descriptor(form, X_F);
			      form.Handle = Result;
			      //AL4_system.WriteLine("11111111111111111111111111111111111111111111\n");
			      //AL4_system.WriteLine("(" + Result + ").........................." +
			      //    "X_F.Obj: " + X_F.Obj.toString());
			      
				  C_Form F = (C_Form)X_F.Obj;
				  C_Screen S = (C_Screen)F.F_Screen_.Obj;
		  
				  form.a_content = new LinearLayout(context_activity);
				  form.a_content.setOrientation(LinearLayout.VERTICAL);
			      MainActivity.main_activity.HView.addView(form.a_content,
			          new LinearLayout.LayoutParams(
			          LinearLayout.LayoutParams.MATCH_PARENT, 
			          LinearLayout.LayoutParams.MATCH_PARENT));
				  
			      form.TV_top = new TextView(context_activity);
			      form.TV_top.setText("- x x x x x x x x x x x -");
			      form.a_content.addView(form.TV_top, new LinearLayout.LayoutParams(
			          LinearLayout.LayoutParams.WRAP_CONTENT,
			          LinearLayout.LayoutParams.WRAP_CONTENT));
			      form.TV_top.setHeight(0);
			      form.TV_top.setFocusable(true);
			      form.TV_top.setFocusableInTouchMode(true);
				  
			      form.v_content = new VScrollView(context_activity, form);
			      form.a_content.addView(form.v_content,
			          new LinearLayout.LayoutParams(
			          LinearLayout.LayoutParams.MATCH_PARENT, 
			          LinearLayout.LayoutParams.MATCH_PARENT));
			          
			      form.h_content = new HScrollView(context_activity, form);
			      form.v_content.addView(form.h_content,
			          new LinearLayout.LayoutParams(
			          LinearLayout.LayoutParams.MATCH_PARENT, 
			          LinearLayout.LayoutParams.MATCH_PARENT));
			          
			      form.Form = new LinearLayout(context_activity);
			      form.Form.setOrientation(LinearLayout.VERTICAL);
			      form.h_content.addView(form.Form,
			          new LinearLayout.LayoutParams(
			              LinearLayout.LayoutParams.MATCH_PARENT,
			              LinearLayout.LayoutParams.MATCH_PARENT));
		  
			      form.Pane_top = new LinearLayout(context_activity);
			      LinearLayout.LayoutParams p_top = new LinearLayout.LayoutParams(
			          LinearLayout.LayoutParams.MATCH_PARENT,
			          LinearLayout.LayoutParams.WRAP_CONTENT);
			      form.Pane_top.setOrientation(LinearLayout.VERTICAL);
			      form.Form.addView(form.Pane_top, p_top);
			      
			      form.Pane_middle = new LinearLayout(context_activity);
			      LinearLayout.LayoutParams p_middle = new LinearLayout.LayoutParams(
			          LinearLayout.LayoutParams.MATCH_PARENT,
			          LinearLayout.LayoutParams.WRAP_CONTENT);
			      form.Form.addView(form.Pane_middle);
			      form.Pane_middle.setLayoutParams(p_middle);
			      
			      form.Pane_left = new LinearLayout(context_activity);
			      LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(
			          LinearLayout.LayoutParams.WRAP_CONTENT,
			          LinearLayout.LayoutParams.MATCH_PARENT);
			      form.Pane_left.setLayoutParams(p);
			      form.Pane_middle.addView(form.Pane_left);
			      form.Pane_left.setOrientation(LinearLayout.HORIZONTAL);
			      
			      form.Pane_client = new LinearLayout(context_activity);
			      p = new LinearLayout.LayoutParams(
			          LinearLayout.LayoutParams.MATCH_PARENT,
			          LinearLayout.LayoutParams.MATCH_PARENT);
			      form.Pane_client.setLayoutParams(p);
			      form.Pane_middle.addView(form.Pane_client);
			      
			      form.Pane_right = new LinearLayout(context_activity);
			      p = new LinearLayout.LayoutParams(
			          LinearLayout.LayoutParams.WRAP_CONTENT,
			          LinearLayout.LayoutParams.MATCH_PARENT);
			      form.Pane_right.setLayoutParams(p);
			      form.Pane_middle.addView(form.Pane_right);
			      
			      form.Pane_bottom = new LinearLayout(context_activity);
			      LinearLayout.LayoutParams p_bottom = new LinearLayout.LayoutParams(
			          LinearLayout.LayoutParams.MATCH_PARENT,
			          LinearLayout.LayoutParams.WRAP_CONTENT);
			      form.Pane_bottom.setOrientation(LinearLayout.VERTICAL);
			      form.Form.addView(form.Pane_bottom);
			      form.Pane_bottom.setLayoutParams(p_bottom);
			      form.Pane_top.setLayoutParams(p_top);
			      
			      if (Forms_shown.size() == 0)
			          activate_form(form);
			      
			      /////////////////////////////////////////////////////////////////////
			      //C_Log_html.M_Log_colored(0,"(" + Result + ")^^^^^^^^^^^^^^^^^^\n");
				  }
				  catch (Exception ex) { report(ex); }
			      return Result;
              }
              catch (Exception ex2) { report(ex2); }
              return 0;
            }
        });
	}
	
	public static int last_decor_bottom = 0;
	public static boolean is_soft_keyboard_visible;
	public static int keyboard_height;
	
	public static void calc_keyboard_height(int upper, int lower) {
		DisplayMetrics dM = new DisplayMetrics();
		context_activity.getWindowManager().getDefaultDisplay()
                .getMetrics(dM);
		int display_h = dM.heightPixels;
		keyboard_height = lower - upper; /// display_h * (lower - upper) / lower;
	}
	
	public static void layout_changed() {
		if (Active_form == null) return;
		int new_bottom = context_activity.decorWindowRect.bottom;
		if (last_decor_bottom == 0) {
			int mode = context_activity.getWindow().getAttributes().softInputMode;
			if ((mode & (
					WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN |
					WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)) != 0)
					is_soft_keyboard_visible = false;
			else if ((mode & (
					WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE |
					WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE)) != 0)
					is_soft_keyboard_visible = true; 
		}
		else {
			if (new_bottom < last_decor_bottom) {
				is_soft_keyboard_visible = true;
				calc_keyboard_height(new_bottom, last_decor_bottom);
			}
			else if (new_bottom > last_decor_bottom) {
				is_soft_keyboard_visible = false;
				calc_keyboard_height(last_decor_bottom, new_bottom);
			}
			force_layout(Active_form.Pane_client);
			force_layout(Active_form.Pane_left);
			force_layout(Active_form.Pane_right);
		}
		if (!is_soft_keyboard_visible) {
			View v = context_activity.getCurrentFocus();
			if (v != null) {
				v.clearFocus();
				v.setSelected(false);
		//////////////////////////////////////////////
		//AL4_system.WriteLine("clear focus on " + v);
		//////////////////////////////////////////////
			}
		}
		last_decor_bottom = new_bottom;
	}
	
	static void force_layout(View v) {
		v.invalidate();
		v.requestLayout();
	}
	
	public static class HScrollView extends HorizontalScrollView {
		public AL4_form form_;
		public HScrollView(Context context, AL4_form form) {
			super(context);
			form_ = form;
		}
		
		@Override 
		public boolean onInterceptTouchEvent(MotionEvent ev) {
			if (form_.Dont_touch) return false;
			return super.onInterceptTouchEvent(ev);
		}
		
		@Override 
		public boolean onTouchEvent(MotionEvent ev) {
			if (form_.Dont_touch) return false;
			return super.onTouchEvent(ev);
		}
	}
    
	public static class VScrollView extends ScrollView {
		public AL4_form form_;
		public VScrollView(Context context, AL4_form form) {
			super(context);
			form_ = form;
			setFillViewport(true);
		}
		
		@Override 
		public boolean onInterceptTouchEvent(MotionEvent ev) {
			if (form_.Dont_touch) return false;
			return super.onInterceptTouchEvent(ev);
		}
				
		@Override 
		public boolean onTouchEvent(MotionEvent ev) {
			if (form_.Dont_touch) return false;
			return super.onTouchEvent(ev);
		}
	}
    
    /*
    // Get form window handle
    //-----------------------
    
    FUN Get_window_handle(INT H|andle_native) ==> INT, NATIVE :
    @   "     RESULT = 0;" . // in JAVA, there is no Handle for window
                             // except using third-party classes/frameworks
                             
	FUN Call_any_change({Form} F|orm_handle), NATIVE:
		INT h|andle_form = F.Handle
		NATIVE @
	@	"	AL4_form form = (AL4_form)AL4_form.All_descr.get(X_h).Jvc;"
		"	C_Form CF = (C_Form)form.AL4Object;"
		"	CF.M_Any_change();" .
		
	// Destroy form object
	//--------------------
	
	FUN Destroy_form(INT H|andle_native), NATIVE :
		"     AL4_form.Do_Destroy_form(X_H);" .
	*/
	public static void Do_Destroy_form(int H)
	{
        //AL4_system.WriteLine("Do_Destroy_form: " + H);
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		AL4_form form = (AL4_form)All_descr.get(H).Jvc;
        form.Deactivate_trays_timers();
        Forms_shown.remove(form);
        form.a_content.setVisibility(View.GONE);
        form.dispose();
        if (H == main_form_handle) do_exit();
	}
	
	public static int main_form_handle = 0;

	/*
	// Close form object
	//--------------------
	
	FUN Form_close(INT H|andle_native), NATIVE :
	@	"     AL4_form form = (AL4_form)AL4_form.All_descr.get(X_H).Jvc;"
		//''    AL4_system.WriteLine("Form_close, H=" + X_H);''
        "	  AL4_form.event_form_closed(X_H, true);"
        "     form.dispose();"
        "	  if (X_H == AL4_form.main_form_handle) {"
        "		AL4_form.do_exit();"
        "		AL4_form.main_form_handle = -1;"
        "	  }" 
        .
        
	*/
	
	public static void activity_started() {
//AL4_system.WriteLine("Activity STARTED, Forms_shown: " + Forms_shown);
		op_sema = new Semaphore(1, true);
		locker = new ReentrantLock();
	}
	
	public static void activity_stopped() {
		do_exit();
//AL4_system.WriteLine("Activity STOPPED, Forms_shown: " + Forms_shown);
	}
	
	public static void need_save_state() {
		if (main_form_handle != 0)
			event_form_closed(main_form_handle, false);
//AL4_system.WriteLine("Activity PAUSED, Forms_shown: " + Forms_shown);
	}
	
	public static void event_form_closed(int H, boolean deactivate) {
	//AL4_system.WriteLine("event_form_closed, deactivate=" + deactivate +
	//", handle=" + H);
			if (H == 0) return;
            try {
            	Ref_obj r = AL4_form.All_descr.get(H).Ref;
            	if (r ==null) return; 
            	C_Form F = (C_Form)r.Obj;
            	if (deactivate) {
            		AL4_form f = (AL4_form)AL4_form.All_descr.get(H).Jvc;
            		f.Deactivate_trays_timers();
            	}
//?{Form}.closed
            	if (operation_started(F, 2, F.hard_link)) {
            	//-----------------------------------------
	            	try {
	                	F.M_closed();
	            	}
	            	finally {
	            		operation_ended(F, 2);
	            	}
            	//-----------------------------------------
            	}
//.
            }
            catch (Exception ex) { report(ex); }
	}
    
	/*
	// Return TRUE if  form is visible
	//--------------------------------
	
	FUN Form_visible(INT H|andle_native) ==> BOOL, NATIVE :
		"    RESULT = AL4_form.Do_Get_form_visible(X_H);" .
	*/
	public static boolean get_property_boolean(Callable<Boolean> code) {
		try {
			if (Looper.getMainLooper() == Looper.myLooper()) {
				return code.call();
			}
			
		    FutureTask<Boolean> task = new FutureTask<>(code);
		    AL4_form.context_activity.runOnUiThread(task);
		    return task.get();
		}
		catch (Exception ex) { report(ex); }
		return false;
	}
	
	public static String get_property_string(Callable<String> code) {
		try {
			if (Looper.getMainLooper() == Looper.myLooper()) {
				return code.call();
			}
			
		    FutureTask<String> task = new FutureTask<>(code);
		    AL4_form.context_activity.runOnUiThread(task);
		    return task.get();
		}
		catch (Exception ex) { report(ex); }
		return "";
	}
	
	public static double get_property_double(Callable<Double> code) {
		try {
			if (Looper.getMainLooper() == Looper.myLooper()) {
				return code.call();
			}
			
		    FutureTask<Double> task = new FutureTask<>(code);
		    AL4_form.context_activity.runOnUiThread(task);
		    return task.get();
		}
		catch (Exception ex) { report(ex); }
		return 0.0;
	}
	
	public static int get_property_int(Callable<Integer> code) {
		try {
			if (Looper.getMainLooper() == Looper.myLooper()) {
				return code.call();
			}
			
		    FutureTask<Integer> task = new FutureTask<>(code);
		    AL4_form.context_activity.runOnUiThread(task);
		    return task.get();
		}
		catch (Exception ex) { report(ex); }
		return 0;
	}
	
	public static Object get_property_object(Callable<Object> code) {
		try {
			if (Looper.getMainLooper() == Looper.myLooper()) {
				return code.call();
			}
			
		    FutureTask<Object> task = new FutureTask<>(code);
		    AL4_form.context_activity.runOnUiThread(task);
		    return task.get();
		}
		catch (Exception ex) { report(ex); }
		return null;
	}
	
	public static boolean Do_Get_form_visible(int H)
	{
        return get_property_boolean(new Callable<Boolean>() {
		        @Override public Boolean call() {
		     	   try {
					   AL4_form form = (AL4_form)AL4_form.All_descr.get(H).Jvc;
					   return form.Form.getVisibility() == View.VISIBLE;
		     	   }
		     	   catch (Exception ex2) { report(ex2); }
		      	   return false;
		        }
		    });
	}
	
	/*
	// Return TRUE if  form is visible
	//--------------------------------
	
	FUN Form_hidden(INT H|andle_native) ==> BOOL, NATIVE : @
       "AL4_form form = (AL4_form)AL4_form.All_descr.get(X_H).Jvc;"
       "RESULT = !form.Hidden;" .
	*/
	

	/*
	// Show or hide form
	//------------------
	
	FUN Show_hide|_form(INT H|andle_native, BOOL Show|_or_hide),
        NATIVE :
		"    AL4_form.Do_show_hide(X_H, X_Show);" .
	
	FUN Show_form_noactivate(INT H|andle_native) : 
		Show_hide(H, TRUE) .		
	*/
      public static void run_on_ui_thread(boolean wait_task, Callable code) {
          try {
              if (Looper.getMainLooper() == Looper.myLooper()) {
                  code.call();
                  return;
              }
			
              FutureTask<Void> task = new FutureTask<>(code);
              AL4_form.context_activity.runOnUiThread(task);
              if (wait_task) task.get();
          }
          catch (Exception ex) { report(ex); }
      }
	
    \\public static int run_on_background_wait(Callable<Integer> code) {
    \\    try {
    \\        if (Looper.getMainLooper() != Looper.myLooper()) {
    \\            return code.call();
    \\        }
    \\        FutureTask<Integer> task = new FutureTask<>(code);
    \\        task.run();
    \\        return task.get();
    \\    }
    \\    catch (Exception ex) { report(ex); }
    \\    return 0;
    \\}
	
    \\public static void run_on_background_thread(FutureTask[] ft_wait, Callable code) {
    \\    try {
    \\        if (Looper.getMainLooper() != Looper.myLooper()) {
    \\            code.call();
    \\            return;
    \\        }
    \\        FutureTask<Void> task = new FutureTask<>(code);
    \\        task.run();
    \\        //task.get();
    \\        ft_wait[0] = task;
    \\    }
    \\    catch (Exception ex) { report(ex); }
    \\}
	
      public static void run_on_background_thread(Callable code) {
          try {
              if (Looper.getMainLooper() != Looper.myLooper()) {
                      code.call();
                      return;
              }
              new Thread(
                  new Runnable() {
                      public void run() {
                          try {
                              code.call();
                          }
                          catch (Exception ex) { report(ex); }
                      }
                  }
              ).start();
          }
          catch (Exception ex) { report(ex); }
      }
	
	public static void Do_show_hide(int H, boolean Show) throws Exception
	{
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                try {
                    AL4_form form = (AL4_form)AL4_form.All_descr.get(H).Jvc;
                    form.Hidden = !Show;
                    form.a_content.setVisibility(Show ? View.VISIBLE : View.GONE);
			        
                    if (Show) {
                        C_Form F = (C_Form)AL4_form.All_descr.get(H).Ref.Obj;
                        if (operation_started(F, 9, F.hard_link)) {
                        //-----------------------------------------
                            \\run_on_background_thread(new Callable<Void>(){
                            \\    @Override public Void call() {
                                      try {
                                          try { F.M_shown(); }
                                          finally { operation_ended(F, 9); }
                                      }
                                      catch(Exception ex) { report(ex); }
                            \\        return null;
                            \\    }
                            \\});
                        //-----------------------------------------
                        }
                        activate_form(form);
                    }
                }
                catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
        //AL4_system.WriteLine("was set visible = " + Show +
        //    ", now = " + form.Form.isVisible());
        //-------------------------------------------------
	}
    
	/*
	// Show form modal
	//------------------
	
	FUN Show_form_modal({Dialog} D|ialog_to_show , {Form} P|arent_form),
            NATIVE :
            INT h|andle_dialog = D.Handle
            INT p|arent_handle = P.Handle
	NATIVE @
    "    AL4_form.Do_show_modal(X_h, X_p);" .
	*/
    AL4_form Pass_dialog_result_to;
    
	public static void Do_show_modal(int H, int P)
	{
//?{Dialog}
        run_on_ui_thread(true, new Callable<Void>(){
            @Override public Void call() {
        
                try {
                    AL4_form form = (AL4_form)AL4_form.All_descr.get(H).Jvc;
                    
                    //AL4_system.WriteLine("Do_show_modal: " + form);
                    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                    
                    AL4_form master = (AL4_form)AL4_form.All_descr.get(P).Jvc;
                    form.Pass_dialog_result_to = master;
                    click_disabled = false;
                    form.Hidden = false;
                    master.a_content.setVisibility(View.GONE);
                    master.Hidden = true;
                    
                    C_Form c_master = (C_Form)master.AL4Object;
                    String save_menu_alias = c_master.F_menu_alias;
                    int save_level_event = c_master.F_level_event;
                    c_master.F_menu_alias = "";
                    c_master.F_level_event = 0;
                    try {                    
	                    C_Dialog dlg = (C_Dialog)form.AL4Object;
	                    
	                    activate_form(form);
	                    doModal(new Callable<Boolean>() {
	                    	@Override
	                    	public Boolean call() {
	                    		return dlg.F_Ready;
	                    	}
	                    });
	                    
	                    form.Hidden = true;
	                    form.a_content.setVisibility(View.GONE);
	                    Forms_shown.remove(form);
                    }
                    finally {
                    	c_master.F_menu_alias = save_menu_alias;
                    	c_master.F_level_event = save_level_event; 
                    }
                    
                    master.Hidden = false;
                    master.a_content.setVisibility(View.VISIBLE);
                }
                catch (Exception ex2) { report(ex2); }
                
                return null;
            }
        });
//.
	}
    
    /*
    // Set modal result
    //---------------------
    
    FUN Set_modal_result(
    INT H|andle_native, STR Result|_set), CALLBACK: .

	// Get form caption
	//---------------------
	
	FUN Get_form_caption(INT H|andle_native) ==> STR, NATIVE :
		"    RESULT = AL4_form.Do_Get_form_caption(X_H);" .
	*/
	public static String Do_Get_form_caption(int H)	{
        \\return get_property_string(new Callable<String>(){
        \\    @Override public String call() {
                try {
                    AL4_form form = (AL4_form)AL4_form.All_descr.get(H).Jvc;
                    return form.Caption;
                }
                catch (Exception ex) { report(ex); }
                return "";
        \\    }
        \\});
	}

	/*
	// Set form caption
	//-----------------
	
	FUN Set_form_caption(
	{Form} F|orm_object, STR V|alue_caption), NATIVE :
		INT h|andle_of_form = F.Handle
		NATIVE @
		"    AL4_form.Do_Set_form_caption(X_h, X_V);" .
	*/
	public static void Do_Set_form_caption(int H, String V)	{
          run_on_ui_thread(false, new Callable<Void>(){
              @Override public Void call() {
                  try {
                      AL4_form form = (AL4_form)AL4_form.All_descr.get(H).Jvc;
                      form.Caption = V;
                      if (form == Active_form) {
                      	context_activity.setTitle(V);
                        //AL4_system.WriteLine("Caption set to [" + V + "]");
                      }
                  }
                  catch (Exception ex) {report(ex);}

                  return null;
              }
          });
	}

	/*
	
FUN Set_window_taskbar_button_progress(
        	{Form} F|orm_object, INT Value|_0_to_100) : .

	
	// Get form left position in points
	//---------------------------------
	
	FUN Get_form_left(
	INT F|orm_native_handler) ==> REAL, NATIVE :
		"    RESULT = AL4_form.Do_get_form_left(X_F); " .
	*/
	public static double Do_get_form_left(int H)
	{
        \\return get_property_double(new Callable<Double>(){
        \\    @Override public Double call() {
                try {
                    AL4_form form = (AL4_form)AL4_form.All_descr.get(H).Jvc;
                    int[] XY = new int[2];
                    form.Form.getLocationInWindow(XY);
                    return 0.0 + XY[0];
                }
                catch (Exception ex) {report(ex);}
                return 0.0;
        \\    }
        \\});
	}

	/*
	// Get form top position in points
	//--------------------------------
	
	FUN Get_form_top(
	INT F|orm_native_handler) ==> REAL, NATIVE :
		"    RESULT = AL4_form.Do_get_form_top(X_F); " .
	*/
	public static double Do_get_form_top(int H)
	{
        \\return get_property_double(new Callable<Double>(){
        \\    @Override public Double call() {
                try {
                    AL4_form form = (AL4_form)AL4_form.All_descr.get(H).Jvc;
                    int[] XY = new int[2];
                    form.Form.getLocationInWindow(XY);
                    return 0.0 + XY[1];
                }
                catch (Exception ex) {report(ex);}
                return 0.0;
        \\    }
        \\});
	}


	/*
	// Set form position in points
	//----------------------------
	
	FUN Set_form_position|_DUMMY(INT F|orm_native_handler,
		REAL L|eft_position, REAL T|op_position) : .
	*/

	/*
	// Get form width in points
	//-------------------------
	
	FUN Get_form_width(
	INT F|orm_native_handler) ==> REAL, NATIVE :
		"    RESULT = AL4_form.Do_Get_form_width(X_F); " .
	*/
	public static double Do_Get_form_width(int H)
	{
        \\return get_property_double(new Callable<Double>(){
        \\    @Override public Double call() {
                try {
                    AL4_form form = (AL4_form)AL4_form.All_descr.get(H).Jvc;
                    return Pixels(form.Form.getWidth());
                }
                catch (Exception ex) {report(ex);}
                return 0.0;
        \\    }
        \\});
	}

	
	/*
	// Get form height in points
	//--------------------------
	
	FUN Get_form_height(
	INT F|orm_native_handler) ==> REAL, NATIVE :
		"    RESULT = AL4_form.Do_Get_form_height(X_F); " .
	*/
	public static double Do_Get_form_height(int H) {
        \\return get_property_double(new Callable<Double>(){
        \\    @Override public Double call() {
                try {
                    AL4_form form = (AL4_form)AL4_form.All_descr.get(H).Jvc;
                    return Pixels(form.Form.getHeight());
                }
                catch (Exception ex) {report(ex);}
                return 0.0;
        \\    }
        \\});
	}
	
	/*
	// Set form size in points
	//------------------------
	
	FUN Set_form_size|_DUMMY(
	INT F|orm_native_handler, REAL W|idth_points, REAL H|eight_points) : .
	
FUN Set_form_minimal_size(INT F|orm_native_handler,
    REAL W|idth_dummy, REAL H|eight_dummy) : .
	
	
	FUN Set_form_bounds(
	INT F|orm_handle, REAL L|eft_position, REAL T|op_position,
	REAL W|idth_form, REAL H|eight_form)
		:
		Set_form_size(F, W, H)
		Set_form_position(F, L, T) .
	
	
	
	FUN Get_form_state(
    INT F|orm_handle_dummy) ==> {Form}.{state} := {state}.'NORMAL' .
    
	FUN Set_form_state(
	INT F|orm_handle, {Form}.{state} V|alue_to_set) : .
    
	FUN Form_client_pos|ition_in_points(
	INT F|orm_native_handler,
	STR What|_X_Y) ==> REAL,
	NATIVE :
		CASE "X" IN What ? BOOL x|_position = TRUE ;
		NATIVE
	@	"    AL4_form form = (AL4_form)AL4_form.All_descr.get(X_F).Jvc;"
    	"	 if (form == null) return 0;"
		"	Point P = new Point(0, 0); // form.PointToScreen(new Point(0,0));"
	    "   if (X_x) "
	    "		RESULT = AL4_form.Pixels(P.x);"
	    "	else RESULT = AL4_form.Pixels(P.y);"
	    .

	
    FUN Form_client_size(
    INT F|orm_native_handler,
    STR What|_side_W_H) ==> REAL,
    NATIVE :
		CASE "W" IN What ? BOOL w|idth_to_get = TRUE ;
    	NATIVE @
    	"	RESULT = AL4_form.get_Form_client_size(X_F, X_w);" .
	*/

	public static double get_Form_client_size(int X_F, boolean X_W) {
        \\return get_property_double(new Callable<Double>(){
        \\    @Override public Double call() {
                try {
                    AL4_form form = (AL4_form)AL4_form.All_descr.get(X_F).Jvc;
                    if (form == null) return 0.0;
                    if (X_W)
                       return AL4_form.Pixels(form.Form.getWidth());
                    else {
                       double RESULT = AL4_form.Pixels(form.Form.getHeight());
                       if (form.Title_line.getVisibility() == View.VISIBLE)
                           RESULT -= AL4_form.Pixels(form.Title_line.getHeight());
                       return RESULT;
                    }
                }
                catch (Exception ex) {report(ex);}
                return 0.0;
        \\    }
        \\});
	}    	
	
	
	/*
        
    FUN Set_form_client_size|_DUMMY(
    INT F|orm_native_handler,
    REAL W|idth_points, REAL H|eight_points) ==> BOOL: .
		
    FUN Set_form_stay_on_top|_DUMMY(
    INT F|orm_native_handler, BOOL T|opmost_Z) : .
        
    FUN Set_form_no_frame(
    INT F|orm_native_handle, BOOL No_frame|_flag), NATIVE: @
    "	AL4_form.do_Set_form_no_frame(X_F, X_No_frame);" .
    
    */

	public static void do_Set_form_no_frame(int X_F, boolean X_No_frame) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                try {
                    if (X_No_frame) {
                        View decor = AL4_form.context_activity.getWindow().getDecorView();
                        decor.setSystemUiVisibility(
                            View.SYSTEM_UI_FLAG_IMMERSIVE
                            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
                        AL4_form.context_activity.requestWindowFeature(
                            Window.FEATURE_NO_TITLE);
                    }
                    else {
                        View decor = AL4_form.context_activity.getWindow().getDecorView();
                        decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
                        ((View)AL4_form.context_activity.findViewById(android.R.id.title))
                            .setVisibility(View.VISIBLE);
                    }
                }
                catch (Exception ex) {report(ex);}

        \\        return null;
        \\    }
        \\});
	}     
    
    /*
    
	FUN Start_move_form(INT F|orm_native_handle): .
	
	FUN Set_form_alpha_tran
	|sparency_0opaque_1invisible(
	INT F|orm_native_handle, REAL Tran|sparency_value): .

    
	FUN Set_form_columns_no_borders|_DUMMY(
	INT F|orm_native_handle, BOOL No_borders|_flag) : .
		
	FUN Set_form_colors|_DUMMY(
		INT F|orm_native_handle, INT FColor|_int, INT BColor|_int) : .
		
	FUN Make_form_tool_window(
	INT F|orm_native_handle, BOOL Yes|_make): .
		
    FUNCTION Is_form_active(INT H|andle_form) ==> BOOL, NATIVE :
		"	RESULT = AL4_form.get_Is_form_active(X_H);" .
		
    FUN Make_form_active(INT H|andle_form),
    UNCOOKED, NATIVE : @
    	"" .
            
		
		
	*/
	public static boolean get_Is_form_active(int X_H) {
        \\return get_property_boolean(new Callable<Boolean>(){
        \\    @Override public Boolean call() {
                try {
                    AL4_form F = (AL4_form)AL4_form.All_descr.get(X_H).Jvc;
                    return F.Form.isFocused();
                }
                catch (Exception ex) {report(ex);}
                return false;
        \\    }
        \\});
	}	
	
	/*		
	
   	FUN Set_form_enabled(
   	INT F|orm_handle, BOOL E|nable_form), NATIVE : @
   	"	AL4_form.do_Set_form_enabled(X_F, X_E);" .
   	
    */
    public static void do_Set_form_enabled(int X_F, boolean X_E) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                try {
                    AL4_form F = (AL4_form)AL4_form.All_descr.get(X_F).Jvc;
                    if (F == null || F.Form == null || F.Form.isEnabled() == X_E)
                        return 
                        \\null
                        ;
                    F.Form.setEnabled(X_E);
                }
                catch (Exception ex) {report(ex);}

        \\        return null;
        \\    }
        \\});
    }
    
	/*
	
	FUN Set_column_padding
	|_not_implemented_in_Android(INT Padding|_pixels) : .
	
	// Create column panel on form
	//----------------------------
	
	FUN Create_column(
	INT F|orm_native_handle, 
	{Form}.{layout} Layout | column,
	REAL	Width | of_column,
	REAL	Label_w | idth,
	INT	Nested_in | _parent_column_handle) ==> INT, NATIVE :
			CASE F == 0 ? ==> ;
			NATIVE @
        "RESULT = AL4_form.Do_Create_column(X_F, X_Layout, X_Width, X_Label_w, "
        "X_Nested_in);" .
	*/
    public static int n_column;
    public static int b_colors[] = {
        0xFF000080,
        0xFF008000,
        0xFF303060,
        0xFF800000,
        0xFF800080,
        0xFF808000,
        0xFF808080,
        0xFFFFFF00,
        0xFF404040,
        0xFF5050A0,
        0xFFC0C0C0,
        0xFF0000FF,
        0xFF00FF00,
        0xFF00FFFF,
        0xFFFF0000,
        0xFFFF00FF
    };
    public static String n_aligns[] = {
        "CLIENT", "LEFT", "RIGHT", "TOP", "BOTTOM"
    };
	
	public static int Do_Create_column(
	int H, int Layout, double Size, double Label_w, int Nested_in) {
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                try {
                    AL4_form F = (AL4_form)All_descr.get(H).Jvc;
                    AL4Column LastCol = new AL4Column(F);
                    F.Columns.add(LastCol);
                    LastCol.Layout = Layout;
                    LastCol.Width_points = Size;
                    LastCol.No_labels = Label_w < 0;
                    //LastCol.Nested_in = Nested_in;
			        
                    ViewGroup parent_for_TV = null;
			        
                    LinearLayout.LayoutParams params = null;
                    switch(Layout) {
                    case 0:
                        params = new LinearLayout.LayoutParams(
                            Size > 0
                            ? Points(LastCol.Width_points)
                            : LinearLayout.LayoutParams.MATCH_PARENT,
                            LinearLayout.LayoutParams.MATCH_PARENT
                            );
                        F.Pane_client.addView(LastCol, params);
                        break;
                    case 1: //left
                        params = new LinearLayout.LayoutParams(
                            Size > 0
                            ? Points(LastCol.Width_points)
                            : LinearLayout.LayoutParams.WRAP_CONTENT,
                            LinearLayout.LayoutParams.MATCH_PARENT);
                        F.Pane_left.addView(LastCol, params);
                        break;
                    case 2: //right
                        params = new LinearLayout.LayoutParams(
                            Size > 0
                            ? Points(LastCol.Width_points)
                            : LinearLayout.LayoutParams.WRAP_CONTENT,
                            LinearLayout.LayoutParams.MATCH_PARENT);
                        F.Pane_right.addView(LastCol, params);
                        break;
                    case 3: //top
                        LastCol.Horizontal = true;
                        params = new LinearLayout.LayoutParams(
                            LinearLayout.LayoutParams.MATCH_PARENT,
                            LinearLayout.LayoutParams.WRAP_CONTENT);
                        F.Pane_top.addView(LastCol, params);
                        parent_for_TV = LastCol;
                        break;
                    case 4: //bottom
                        LastCol.Horizontal = true;
                        params = new LinearLayout.LayoutParams(
                            LinearLayout.LayoutParams.MATCH_PARENT,
                            LinearLayout.LayoutParams.WRAP_CONTENT);
                        F.Pane_bottom.addView(LastCol, params);
                        parent_for_TV = LastCol;
                        break;
                    }
			    	
                    if (!LastCol.Horizontal) {
                        LastCol.setOrientation(LinearLayout.VERTICAL);
                        LastCol.table_content = LastCol.No_labels
                            ? new LinearLayout(context_activity)
                            : new TableLayout(context_activity);
                        LastCol.table_content.setLayoutParams(
                            LastCol.No_labels
                            ? new LinearLayout.LayoutParams(
                                Size > 0
                                ? Points(LastCol.Width_points)
                                : TableLayout.LayoutParams.WRAP_CONTENT,
                                TableLayout.LayoutParams.WRAP_CONTENT)
                            : new TableLayout.LayoutParams(
                                Size > 0
                                ? Points(LastCol.Width_points)
                                : TableLayout.LayoutParams.WRAP_CONTENT,
                                TableLayout.LayoutParams.WRAP_CONTENT));
                        LastCol.addView(LastCol.table_content);
				        
                        TableRow row = new TableRow(context_activity);
                        row.setLayoutParams(new TableLayout.LayoutParams(
                            TableLayout.LayoutParams.MATCH_PARENT,
                            TableLayout.LayoutParams.WRAP_CONTENT));
                        LastCol.table_content.addView(row);
				        
                        parent_for_TV = row;
				                
                    }
                    LastCol.TV = new TextView(context_activity);
                    //TV.setBackgroundColor(b_colors[n_column % b_colors.length]);
                    LastCol.TV.setText("- x x x x x x -");
                    //"column " + (++n_column) + " align " + n_aligns[Layout] + ' ');
                    parent_for_TV.addView(LastCol.TV, new TableRow.LayoutParams(
                        TableRow.LayoutParams.WRAP_CONTENT,
                        TableRow.LayoutParams.WRAP_CONTENT));
			        	
                    LastCol.TV.setHeight(0);
                    if (LastCol.Horizontal)
                        LastCol.TV.setWidth(0);
			        
                    if (!LastCol.No_labels && !LastCol.Horizontal) {
                        LastCol.TV = new TextView(context_activity);
                        //TV.setBackgroundColor(b_colors[n_column % b_colors.length]);
                        LastCol.TV.setText("- x x x x x x -");
                        parent_for_TV.addView(LastCol.TV, new TableRow.LayoutParams(
                            TableRow.LayoutParams.WRAP_CONTENT,
                            TableRow.LayoutParams.WRAP_CONTENT));
                        LastCol.TV.setHeight(0);
                        LastCol.TV.setHeight(0);
                    }
			        
                    // this stops auto-scrolling to an edit text control focused
                    LastCol.TV.setFocusable(true);
                    LastCol.TV.setFocusableInTouchMode(true);
			    	
			                
                    //AL4_system.WriteLine("created column " + LastCol.Handle);
                    F.HCurrent_column_handle = LastCol.Handle;
        //if (LastCol.Horizontal) {//////////////////////////////////////////////
        //AL4_system.WriteLine("added column Nested, Handle=" + LastCol.Handle);
        //} /////////////////////////////////////////////////////////////////////
                    return LastCol.Handle;
                }
                catch (Exception ex) {report(ex);}
                return 0;
        \\    }
        \\});
	}
    
   public void Adjust_columns() {
        //adjusting_columns = true;
        try {
        }
        finally {
            //adjusting_columns = false;
        }
    }


	/*
	
FUN Get_column_layout(
INT C|olumn_handle) ==> {Form}.{layout}, NATIVE : @
   "AL4_form.AL4Column LastCol = (AL4_form.AL4Column)"
   "                      AL4_form.All_descr.get(X_C).Jvc; "
   "RESULT = (byte)LastCol.Layout;" .

FUN Get_nested_in(
INT C|olumn_handle) ==> INT : .

	
	
	FUN Form_suspend_layout(
	INT Handle|_of_form_to_suspend) : .
	
	FUN Form_resume_layout(
	INT Handle|_of_form_to_resume), CALLBACK : .
	
    FUN Form_suspend_column(
    INT Handle|_of_form, INT Col|umn_index): .
    
    FUN Form_resume_column(
    INT Handle|_of_form, INT Col|umn_index): .
	
    FUN Get_form_column_controls_layout(
    	INT Col|umn_handler) ==> {Form}.{controls_layout} : .

    FUN Set_form_column_controls_layout(
    	INT Col|umn_handler,
    	{controls_layout} CL|ayout_controls) : .

    FUN Get_column_label_width|_limit|_Dummy(
    	INT C|olumn_handle) ==> REAL : .

    // Set column label width which is sufficient short to label next control 
    // to right (rather then place it below):
	//-------------------------
	
	FUN Set_column_label_width_limit|_Dummy(
	INT C|olumn_handle, REAL Lab|el_width): .
	
    FUN Get_form_column_uses_margins(
    INT C|olumn_handle|DUMMY) ==> BOOL := TRUE .
    
    FUN Set_form_column_margins(
    INT C|olumn_handle, BOOL Use_margins) : .
	
    
FUN Set_column_position_pixels(
INT C|olumn_handle, INT Left|_position, INT Top|_position) : .

FUN Set_column_width_pixels(
INT C|olumn_handle, INT Width|_pixels) : .

FUN Set_column_height_pixels(
INT C|olumn_handle, INT Height|_pixels) : . 

FUN Column_children_count(INT C|olumn_handle) ==> INT, NATIVE : @
    "AL4_form.AL4Column Col = "
    "       (AL4_form.AL4Column)AL4_form.All_descr.get(X_C).Jvc;"   
    "RESULT = Col.Child_controls.size();" .

FUN Column_child(INT C|olumn_handle, INT Index|_of_child) ==> {Control},
NATIVE : @
    "AL4_form.AL4Column Col = "
    "       (AL4_form.AL4Column)AL4_form.All_descr.get(X_C).Jvc;"
    "RESULT = X_Index < 0 || X_Index >= Col.Child_controls.size()"
    " 		? C_Control.NoneObj_C_Control.hard_link"
    "		: Col.Child_controls.get(X_Index);"
    "RESULT.Count += 2;" .



FUN Adjust_control_location(INT C|olumn_handle) : .

    // Set column sizes
    //-------------------------
    
    FUN Set_form_column_width(
    INT C|olumn_handle, REAL Width|_value), NATIVE :
		CASE C == 0 ? ==> ;
		NATIVE @
		" AL4_form.do_Set_form_column_size(X_C, X_Width, true);" .
		
    FUN Set_form_column_height(
    INT C|olumn_handle, REAL Height|_value),	
        NATIVE : @
        " AL4_form.do_Set_form_column_size(X_C, X_Height, false);" .
    */
   	public static void do_Set_form_column_size(int X_C, double Size, boolean is_width) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      AL4_form.AL4Column LastCol = (AL4_form.AL4Column)
                          AL4_form.All_descr.get(X_C).Jvc;
                      if (is_width) LastCol.Width_points = Size;
                      else LastCol.Height_points = Size;
                  }
                  catch (Exception ex) {report(ex);}
                  
        \\        return null;
        \\    }
        \\});
   	}
    /*

    FUN Set_form_column_auto_arrange|_DUMMYe(
        INT C|heckbox_handle, BOOL A|uto_arrange) : .
        
	FUN Set_default_forms_font(
	{Screen} Screen|_object, STR Face|name, REAL Size|points)
		:
		Screen.Default_font_face = Face
		Screen.Default_font_size = Size .
	
    FUN Set_form_column_font(
        INT C|olumn_handle,
        STR Face | name,
		REAL Size| font,
		STR Styles| B_I_U_S), UNCOOKED: .
        
	FUN Set_column_alias(
		INT C|olumn_handle, STR Alias|_of_column), NATIVE :
	@	"   AL4_form.AL4Column Col = "
        "       (AL4_form.AL4Column)AL4_form.All_descr.get(X_C).Jvc;"
        "   Col.Alias = X_Alias;" .
        
	FUN Disable_column_scroll(INT C|olumn_handle) : .    

        
FUN Get_column_pos_pixels(
INT C|olumn_handle, STR W|hat_L_T_W_H) ==> INT : .

    
	// Get column width in points 
	//----------------------------
	
	FUN Get_column_width(
	INT C|olumn_handler) ==> REAL, NATIVE :
		"    RESULT = AL4_form.Do_Get_column_width(X_C);" .
	*/
	public static double Do_Get_column_width(int H) {
        \\return get_property_double(new Callable<Double>(){
        \\    @Override public Double call() {
                  try {
                      AL4Column Col = (AL4Column)All_descr.get(H).Jvc;
                      return Pixels(Col.getWidth());
                  }
                  catch (Exception ex) {report(ex);}
                  return 0.0;
        \\    }
        \\});
	}

	/*
	// Get column height in points
	//----------------------------
	
	FUN Get_column_height(
	INT C|olumn_handler) ==> REAL, NATIVE :
		"    RESULT = AL4_form.Do_Get_column_height(X_C);" .
	*/
	public static double Do_Get_column_height(int H)
	{
        \\return get_property_double(new Callable<Double>(){
        \\    @Override public Double call() {
                  try {
                      AL4Column Col = (AL4Column)All_descr.get(H).Jvc;
                      return Pixels(Col.getHeight());
                  }
                  catch (Exception ex) {report(ex);}
                  return 0.0;
        \\    }
        \\});
	}

    /*
    // Get column (parent to a certain control) left position
    //----------------------------
    
    FUN Get_parent_column_visible(
    INT Handle|control) ==> BOOL, NATIVE :
        "    RESULT = AL4_form.Do_Get_parent_column_visible(X_Handle);" .
    */
    public static boolean Do_Get_parent_column_visible(int H)
    {
        \\return get_property_boolean(new Callable<Boolean>(){
        \\    @Override public Boolean call() {
                  try {
                  //AL4_system.WriteLine("getting parent column for " + H);
                      View C = (View)All_descr.get(H).Jvc;
                      AL4Column Col = Get_parent_column(C);
                      if (Col == null) return false;
                  //AL4_system.WriteLine("got parent column: " + Col);
                      //double L = 0;
                      return Col.getVisibility() == View.VISIBLE;
                  }
                  catch(Exception ex) {report(ex);}
                  return false;
        \\    }
        \\});
    }

    /*
    // Get column (parent to a certain control) left position
    //----------------------------
    
    FUN Get_parent_column_left(
    INT Handle|control) ==> REAL, NATIVE :
        "    RESULT = AL4_form.Do_Get_parent_column_left(X_Handle);" .
    */
    public static AL4Column Get_parent_column(View V) {
		View C = V;
        while (C != null) {
            ViewParent P = C.getParent();
            if (P instanceof AL4Column) return (AL4Column)P;
            if (P == null || !(P instanceof View)) return null;
            C = (View)P;
        }
        return null;
    }
    
    public static double Do_Get_parent_column_left(int H)
    {
        \\return get_property_double(new Callable<Double>(){
        \\    @Override public Double call() {
                  try {
                  //AL4_system.WriteLine("getting parent column for " + H);
                      View C = (View)All_descr.get(H).Jvc;
                      AL4Column Col = Get_parent_column(C);
                      if (Col == null) return 0.0;
                  //AL4_system.WriteLine("got parent column: " + Col);
                      //double L = 0;
                      int XY[] = new int[2];
                      Col.getLocationInWindow(XY);
                      int Result = XY[0];
                      //Col.Form_.Form.getLocationInWindow(XY);
                      //Result -= XY[0];
                      return Pixels(Result);
                  }
                  catch(Exception ex) {report(ex);}
                  return 0.0;
        \\    }
        \\});
    }

    /*
    // Get column (parent to a certain control) top position
    //----------------------------
    
    FUN Get_parent_column_top(
    INT Handle|control) ==> REAL, NATIVE :
        "    RESULT = AL4_form.Do_Get_parent_column_top(X_Handle);" .
    */
    public static double Do_Get_parent_column_top(int H)
    {
        \\return get_property_double(new Callable<Double>(){
        \\    @Override public Double call() {
                  try {
                      View C = (View)All_descr.get(H).Jvc;
                      AL4Column Col = Get_parent_column(C);
                      if (Col == null) return 0.0;
                      int XY[] = new int[2];
                      Col.getLocationInWindow(XY);
                      int Result = XY[1];
                  //AL4_system.WriteLine("Get_parent_column_top{" + Col.Alias + "}: "
                  //+ Result + "px on screen" +
                  //" - its parent top(" + XY[1] + ") " //"--> " + (Result - XY[1]) +
                  //+ " ==> " + Pixels(Result) + "pts");
                      return Pixels(Result);
                  }
                  catch(Exception ex) {report(ex);}
                  return 0.0;
        \\    }
        \\});
    }

	/*
	// Get column visibility
	//-----------------------
	
	FUN Get_column_visible(
	INT H|andle_column) ==> BOOL, NATIVE :
		"     RESULT = AL4_form.Do_Get_column_visible(X_H);" .
	*/
    public static boolean Do_Get_column_visible(int H) {
        \\return get_property_boolean(new Callable<Boolean>(){
        \\    @Override public Boolean call() {
                 try {
                     AL4Column col = (AL4Column)AL4_form.All_descr.get(H).Jvc;
                     return col.getVisibility() == View.VISIBLE;
                 }
                 catch (Exception ex2) { report(ex2); }
                 return false;
        \\    }
        \\});
    }

	/*

	FUN Get_column_hidden(
	INT H|andle_column) ==> BOOL, NATIVE :
		"     RESULT = AL4_form.Do_Get_column_hidden(X_H);" .
	*/
    public static boolean Do_Get_column_hidden(int H) {
        \\return get_property_boolean(new Callable<Boolean>(){
        \\    @Override public Boolean call() {
                 try {
                     AL4Column col = (AL4Column)AL4_form.All_descr.get(H).Jvc;
                     return col.getVisibility() != View.VISIBLE;
                 }
                 catch (Exception ex2) { report(ex2); }
                 return false;
        \\    }
        \\});
    }

	/*
	// Set column visibility
	//-----------------------
	
	FUN Set_column_visible(
	INT H|andle_column, BOOL V|isible_value), NATIVE :
		"     AL4_form.Do_Set_column_visible(X_H, X_V);" .
        
	*/
    public static void Do_Set_column_visible(int H, boolean V) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      AL4Column col = (AL4Column)AL4_form.All_descr.get(H).Jvc;
                      col.setVisibility(V ? View.VISIBLE : View.GONE);
                  }
                  catch (Exception ex3) { report(ex3); }
        \\        return null;
        \\    }
        \\});
    }
    
	/*
        
    FUN Adjust_columns|_DUMMY(INT F|orm_native_handle) : .
    
	
	FUN Get_form_mobile_config|uration(
	INT F|orm_handle) ==> {Form}.{mobile_config} : .
			
	FUN Set_form_mobile_config|uration(
	INT F|orm_handle, {mobile_config} MC|onfiguration_to_set)
	: .
		
	// Set current column handler (it will be a parent for all new controls)
	//----------------------------------------------------------------------
	
	FUN Set_form_current_column_handle(
	INT H|andler_form, INT Col|umn_handler), NATIVE :
		"     AL4_form.Do_Set_form_current_column_handle(X_H, X_Col);" .
	*/
    public int HCurrent_column_handle;
    
    public static void Do_Set_form_current_column_handle(int H, int Col) {
        AL4_form f = (AL4_form)AL4_form.All_descr.get(H).Jvc;
        f.HCurrent_column_handle = Col;
    }
    
	/*
	
FUN Control_suspend({Control} T|he_control) : .
        
FUN Control_resume({Control} T|he_control) : .	
	// Destroy control object
	//-----------------------
	
	FUN Destroy_control|_native(
	{Control} C|ontrol_object)
		:
        STR save|_current_column = C.Form_.Current_column
        C.Form_.Set_current_column(Parent_column_alias(C))
        do_destroy_control(C.Form_.Handle, C.Handle) 
        C.Form_.Set_current_column(save) .
    
	FUN do_destroy_control|_native(
	INT H|andle_form, INT Contr|ol_handle), NATIVE :
		"     AL4_form.Do_Destroy_control(X_H, X_Contr);" .
		
	FUN Parent_column_alias(
        {Control} C|ontrol_which_parent_alias_needed) ==> STR, NATIVE: @
        "	RESULT = AL4_form.Parent_column_alias(X_C);" .

	*/
	
	public static String Parent_column_alias(Ref_obj CC) {
    	View C = (View)AL4_form.All_descr.get(
    			((C_Control)CC.Obj).F_Handle).Jvc;
    	AL4Column Col = Get_parent_column(C); 
    	return Col.Alias;
    }

	public static void Do_Destroy_control(int X_F, int X_Contr)
	{
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      AL4Column Col = Get_parent_for_new_control(X_F);
                      View Contr = (View)AL4_form.All_descr.get(X_Contr).Jvc;
                      Col.removeView(Contr);
                      AL4_form.ReleaseDescriptor(X_Contr);
                  }
                  catch (Exception ex) {report(ex);}
        \\        return null;
        \\    }
        \\});
	}

	/*
	// Terminate application immediately
	//----------------------------------
	
	FUN Application_terminate, NATIVE : @   
	"    AL4_form.Application_terminated = true;"
	"    System.exit(0);" .
	*/

	/*
	// Get active control on form
	//---------------------------
	
	FUN Obtain_active_control(
	{Form} F|orm_object) ==> {Control}, NATIVE :
		INT h|andle_form = F.Handle
		NATIVE @
		"    Ref_obj r = AL4_form.Do_Obtain_active_control(X_h);" 
		"	 if (r != null) RESULT = r;" .
	*/
	
	public static Ref_obj Do_Obtain_active_control(int H)
	{
        \\return (Ref_obj)get_property_object(new Callable<Object>(){
        \\    @Override public Object call() {
                  try {
                      AL4_form F = (AL4_form)AL4_form.All_descr.get(H).Jvc;
                      View a = context_activity.getCurrentFocus();
                      if (a != null) {
                          Ref_obj r = Get_control_ref(a, true);
                          if (r != null) {
                              return r;
                          }
                      }
                      return C_Control.NoneObj_C_Control.hard_link;
                  }
                  catch (Exception ex) {report(ex);}
                  return null;
        \\    }
        \\});
	}

	/*
	// Activate certain control
	//-------------------------
	
	FUN Activate_control(
	INT H|andle_form, INT C|ontrol_native), NATIVE :
		"     AL4_form.Do_Activate_control(X_C);" .
	*/
	public static void Do_Activate_control(int X)
	{
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      Object x = AL4_form.All_descr.get(X).Jvc;
                      if (x instanceof View) {
                          View C = (View)x;
                          C.requestFocus();
                      }
                  }
                  catch (Exception ex) {report(ex);}
        \\        return null;
        \\    }
        \\});
	}

	/*
	// Move control into view area on parent column if  it is scrolled out
	//--------------------------------------------------------------------
	
    //FUN Make_control_visible(
    //INT H|andle_form, INT C|ontrol_to_move_to_view), NATIVE :
    //    "     AL4_form.Do_Make_visible(X_H, X_C);" .
	*/

	/*
	// Get control left position in points (on its column)
	//----------------------------------------------------
	
	FUN Get_control_left|_position(
	{Control} C|ontrol_object) ==> REAL, NATIVE :
		INT h|andle_control = C.Handle
		NATIVE @ "     RESULT = AL4_form.Do_Get_control_left(X_h);" .
	*/
	public static double Do_Get_control_left(int H)
	{
        \\return get_property_double(new Callable<Double>(){
        \\    @Override public Double call() {
                  try {
                      View C = (View)AL4_form.All_descr.get(H).Jvc;
                      int XY[] = new int[2];
                  //AL4_system.WriteLine("getting location for " + H + ": " + C);
                      C.getLocationInWindow(XY);
                  //AL4_system.WriteLine("got location for " + H + ": " + XY[0] + ", " + XY[1]);
                      int Result = XY[0];
                      AL4Column Col = Get_parent_column(C);
                      if (Col != null) {
                          Col.Form_.Form.getLocationInWindow(XY);
                          Result -= XY[0];
                      }
                      return Pixels(Result);
                  }
                  catch (Exception ex) {report(ex);}
                  return 0.0;
        \\    }
        \\});
	}

	/*
	// Get control top position in points (on its column)
	//---------------------------------------------------
	
	FUN Get_control_top|_position(
	{Control} C|ontrol_object) ==> REAL, NATIVE :
		INT h|andle_control = C.Handle
		NATIVE @ "     RESULT = AL4_form.Do_Get_control_top(X_h);" .
	*/
	public static double Do_Get_control_top(int H)
	{
        \\return get_property_double(new Callable<Double>(){
        \\    @Override public Double call() {
                  try {
                      View C = (View)AL4_form.All_descr.get(H).Jvc;
                      int XY[] = new int[2];
                      C.getLocationInWindow(XY);
                      int Result = XY[1];
              //AL4_system.WriteLine("control [" +
              //((C_Control)AL4_form.All_descr.get(H).Ref.Obj).F_Alias +
              //"] on screen top=" + Result);
                      AL4Column Col = Get_parent_column(C);
                      if (Col != null) {
                          Col.getLocationInWindow(XY);
              //AL4_system.WriteLine("column {" + Col.Alias + "} on screen Y = [" +
              //XY[1] + "] = " + (Result-XY[1]) + "px --> " +
              //Pixels(Result - XY[1]) + "pts");
                          Result -= XY[1];
                      }
                      return Pixels(Result);
                  }
                  catch (Exception ex) {report(ex);}
                  return 0.0;
        \\    }
        \\});
	}

	/*
	// Set control position in points
	//-------------------------------
	
	FUN Set_control_pos|ition|_DUMMY(
	INT C|ontrol_to_pos, REAL X|_offset, REAL Y|_offset): .
	
    // Is autosized ?
    //---------------------------
    
    FUN Is_autosized_control(
    INT C|ontrol_to_check_DUMMY) ==> BOOL :
        RESULT = TRUE . 
        
	// Get control width in points
	//----------------------------
	
	FUN Get_control_width(
	{Control} C|ontrol_object) ==> REAL, NATIVE :
		INT h|andle_control = C.Handle
		NATIVE @ "     RESULT = AL4_form.Do_Get_control_width(X_h);" .
	*/
	public static double Do_Get_control_width(int H)
	{
        \\return get_property_double(new Callable<Double>(){
        \\    @Override public Double call() {
                  try {
                      View C = (View)AL4_form.All_descr.get(H).Jvc;
                      int result = C.getWidth();
                      //AL4Column col = Get_parent_column(C);
                      //if (col != null && col.getWidth() < result)
                      //    result = col.getWidth();
                      return Pixels(result);
                  }
                  catch (Exception ex) {report(ex);}
                  return 0.0;
        \\    }
        \\});
	}
	
    /*
    
    TODO: "Implement Get_label_desired_width" .
    
    FUN Get_label_desired_width(
    {Control} C|ontrol_label) ==> REAL :
    	= Get_control_width(C) .
    */	
    

	/*
	// Get control height in points
	//-----------------------------
	
	FUN Get_control_height(
	{Control} C|ontrol_object) ==> REAL, NATIVE :
		INT h|andle_control = C.Handle
		NATIVE @ "     RESULT = AL4_form.Do_Get_control_height(X_h);" .
	*/
	public static double Do_Get_control_height(int H)
	{
        \\return get_property_double(new Callable<Double>(){
        \\    @Override public Double call() {
                  try {
                      View C = (View)AL4_form.All_descr.get(H).Jvc;
                      return Pixels(C.getHeight());
                  }
                  catch (Exception ex) {report(ex);}
                  return 0.0;
        \\    }
        \\});
	}
	/*
    FUN Get_control_client_width(
    {Control} C|ontrol_object) ==> REAL, NATIVE :
		INT h|andle_control = C.Handle
		CASE h == 0 ? ==> ;
		NATIVE @
        "     RESULT = AL4_form.Do_Get_control_client_width(X_h);" .
    */
    public static double Do_Get_control_client_width(int H)
    {
		\\return get_property_double(new Callable<Double>(){
        \\    @Override public Double call() {
                  try {
                      View C = (View)AL4_form.All_descr.get(H).Jvc;
                      return Pixels(C.getWidth());
                  }
                  catch (Exception ex) {report(ex);}
                  return 0.0;
        \\    }
        \\});    
    }
    /*
    FUN Get_control_client_height(
    {Control} C|ontrol_object) ==> REAL, NATIVE :
		INT h|andle_control = C.Handle
		CASE h == 0 ? ==> ;
		NATIVE @
        "     RESULT = AL4_form.Do_Get_control_client_height(X_h);" .
    */
    public static double Do_Get_control_client_height(int H)
    {
		\\return get_property_double(new Callable<Double>(){
        \\    @Override public Double call() {
                  try {
                      View C = (View)AL4_form.All_descr.get(H).Jvc;
                      return Pixels(C.getHeight());
                  }
                  catch (Exception ex) {report(ex);}
                  return 0.0;
        \\    }
        \\});    
    }
	/*
	
        FUN Set_control_size_auto(
        	INT C|ontrol_to_pos|DUMMY, 
        	REAL W|idth_set|DUMMY, 
        	REAL H|eight_set|DUMMY) : .
	
	
	// Set control size in points
	//---------------------------
	
	FUN Set_control_size|_DUMMYe(
	INT C|ontrol_to_pos, REAL W|idth_set, REAL H|eight_set), NATIVE : @
	"AL4_form.do_Set_control_size(X_C, X_W, X_H);" .
	*/
	public static void do_Set_control_size(int X_C, double X_W, double X_H) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      View C = (View)AL4_form.All_descr.get(X_C).Jvc;
                      if (C instanceof TextView) {
                          TextView t = (TextView)C;
                          if (X_W > 0)
                              t.setWidth(Points(X_W));
                          if (X_H > 0)
                              t.setHeight(Points(X_H));
                      }
                  }
                  catch (Exception ex) { report(ex); }
        \\        return null;
        \\    }
        \\});
	}
	
	
	/*
	
	// Set control text
	//-----------------
	
	FUN Set_control_caption(
	{Control} C|ontrol_object, STR Text|_set), NATIVE :
		INT h|andle_control = C.Handle
		NATIVE @ "     AL4_form.Do_Set_control_caption(X_h, X_Text);" .
	*/
	public static void Do_Set_control_caption(int H, String Text)
	{
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      View C = (View)AL4_form.All_descr.get(H).Jvc;
                      if (C instanceof TextView) {
                          TextView v = (TextView)C;
                          //int h = v.getHeight();
                          v.setText(Text);
                          v.invalidate();
                          //if (v.getTextSize() > h)
                          //	v.setTextSize(v.getHeight() - Points(2 * 25f));
                          //------------------------------------------------------------------
                          //AL4_system.WriteLine("Text set for control(" + H + "):[" +
                          //Text + "]");
                      }
                  }
                  catch (Exception ex3) { report(ex3); }
        \\        return null;
        \\    }
        \\});
	}
	
	/*
	// Return control text
	//--------------------
	
	FUN Get_control_caption(
	{Control} C|ontrol_object) ==> STR, NATIVE :
		INT h|andle_control = C.Handle
		NATIVE @ "     RESULT = AL4_form.Do_Get_control_caption(X_h);" .
	*/
	public static String Do_Get_control_caption(int H)
	{
        \\return get_property_string(new Callable<String>(){
        \\    @Override public String call() {
                  try {
                      View C = (View)AL4_form.All_descr.get(H).Jvc;
                      if (C instanceof TextView) {
                          return ((TextView)C).getText().toString();
                      }
                  }
                  catch (Exception ex) { report(ex);}
                  return "";
        \\    }
        \\});
	}

	/*
	
	FUN Set_control_align(
    {Control} C|ontrol_object, {Control}.{text_align} TA|lignment), NATIVE 
    	:
    	INT h|andle_control = C.Handle
    	CASE h==0 ? ==> ;
    	NATIVE @     
        "View C = (View)AL4_form.All_descr.get(X_h).Jvc;"
        "int dg = Gravity.LEFT;"    
        "switch (X_TA) {"
        "case 1: dg = Gravity.CENTER_HORIZONTAL; break;"
        "case 2: dg = Gravity.RIGHT; break;"     
        "}"     
        "if (C instanceof TextView) { ((TextView)C).setGravity(dg); }" .
            
	// Return TRUE if control is DISABLED (!)
	//---------------------------------------
	
	FUN Get_control_disabled(
	{Control} C|ontrol_object) ==> BOOL, NATIVE :
		INT h|andle_control = C.Handle
		NATIVE @ "     RESULT = AL4_form.Do_Get_disabled(X_h);" .
	*/
	public static boolean Do_Get_disabled(int H)
	{
        \\return get_property_boolean(new Callable<Boolean>(){
        \\    @Override public Boolean call() {
                  try {
                      View C = (View)AL4_form.All_descr.get(H).Jvc;
                      return !C.isEnabled();
                  }
                  catch (Exception ex) { report(ex); }
                  return false;
        \\    }
        \\});
	}

	/*
	// Set control disabled (TRUE - disabled, FALSE - enabled)
	//--------------------------------------------------------
	
	FUN Set_control_disabled(
	{Control} C|ontrol_object, BOOL Disable|_control), NATIVE :
		INT h|andle_control = C.Handle
		NATIVE @ "     AL4_form.Do_Set_disabled(X_h, X_Disable);" .
	*/
	public static void Do_Set_disabled(int H, boolean D)
	{
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      View C = (View)AL4_form.All_descr.get(H).Jvc;
                      C.setEnabled(!D);
                  }
                  catch (Exception ex) { report(ex); }
        \\        return null;
        \\    }
        \\});
	}

	/*
	// Get TRUE when control is hidden (FALSE if visible)
	//---------------------------------------------------
	
	FUN Get_control_hidden(
	{Control} C|ontrol_object) ==> BOOL, NATIVE :
		INT h|andle_control = C.Handle
		NATIVE @ "     RESULT = AL4_form.Do_Get_hidden(X_h);" .
	*/
	public static boolean Do_Get_hidden(int H)
	{
        \\return get_property_boolean(new Callable<Boolean>(){
        \\    @Override public Boolean call() {
                  try {
                      View C = (View)AL4_form.All_descr.get(H).Jvc;
                      return C.getVisibility() == View.GONE;
                  }
                  catch (Exception ex) { report(ex); }
                  return false;
        \\    }
        \\});
	}

	/*
	// Set control hidden state (TRUE - hidden, FALSE - Visible)
	//----------------------------------------------------------
	
	FUN Set_control_hidden(
	{Control} C|ontrol_object, BOOL M|ake_hidden), NATIVE :
		INT h|andle_control = C.Handle
		NATIVE @ "     AL4_form.Do_Set_hidden(X_h, X_M);" .
	*/
	public static void Do_Set_hidden(int H, boolean M)
	{
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      View C = (View)AL4_form.All_descr.get(H).Jvc;
                      C.setVisibility(M ? View.GONE : View.VISIBLE);
                  }
                  catch (Exception ex) { report(ex); }
        \\        return null;
        \\    }
        \\});
	}
    
    /*
    
    FUN Get_control_foreground|_color(
    {Control} C|ontrol_object) ==> INT, NATIVE :
		INT h|andle_control = C.Handle
		NATIVE @ "	RESULT = AL4_form.Do_Get_control_foreground(X_h);" .
	*/
	public static int Do_Get_control_foreground(int X_H) {
        \\return get_property_int(new Callable<Integer>() {
        \\    @Override public Integer call() {
                  try {
                      View C = (View)AL4_form.All_descr.get(X_H).Jvc;
                      Color c = Color.valueOf(Color.BLACK);
                      if (C instanceof TextView)
                          c = Color.valueOf(((TextView)C).getCurrentTextColor());
                      return ((int)(c.red() * 256))
                           | (((int)(c.green() * 255)) << 8)
                           | (((int)(c.blue() * 255)) << 16)
                           | (((int)(c.alpha() * 255)) << 24);
                  }
                  catch (Exception ex) { report(ex); }
                  return 0;
        \\    }
        \\});
	}	
	
	/*
	
    FUN Set_control_foreground(
    {Control} C|ontrol_object, INT Color|_set), NATIVE :
		INT h|andle_control = C.Handle
		NATIVE @ "	AL4_form.Do_Set_control_foreground(X_h, X_Color);" .
    */
    public static void Do_Set_control_foreground(int X_H, int X_Color) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      View C = (View)AL4_form.All_descr.get(X_H).Jvc;
                      if (!(C instanceof TextView))
                      	return 
                      	\\null
                      	;
                      int c = Color.argb( 255, X_Color&0xff, (X_Color>>8)&0xff,
                          (X_Color>>16)&0xff);
                      ((TextView)C).setTextColor(c);
                  }
                  catch (Exception ex) { report(ex); }
        \\        return null;
        \\    }
        \\});
    }
	/*
	
    FUN Get_control_background(
    {Control} C|ontrol_object) ==> INT, NATIVE :
		INT h|andle_control = C.Handle
		NATIVE @ "	RESULT = AL4_form.Do_Get_control_background(X_h);" .	
    */
    public static int Do_Get_control_background(int X_H) {
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                      View C = (View)AL4_form.All_descr.get(X_H).Jvc;
                      Drawable d = C.getBackground();
                      if (d instanceof ColorDrawable) {
                          Color c = Color.valueOf(((ColorDrawable)d).getColor());
                          return ((int)(c.red() * 256))
                               | (((int)(c.green() * 255)) << 8)
                               | (((int)(c.blue() * 255)) << 16)
                               | (((int)(c.alpha() * 255)) << 24);
                      }
                  }
                  catch (Exception ex) { report(ex); }
                  return 0xFF808080;
        \\    }
        \\});
    }
    /*
    
    FUN Set_control_background(
    {Control} C|ontrol_object, INT Color|_set), NATIVE :
		INT h|andle_control = C.Handle
		NATIVE @ "	AL4_form.Do_Set_control_background(X_h, X_Color);" .
    */
    public static void Do_Set_control_background(int X_H, int X_Color) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      View C = (View)AL4_form.All_descr.get(X_H).Jvc;
                      C.setBackgroundColor(
                          Color.rgb(X_Color&0xff, (X_Color>>8)&0xff,
                          (X_Color>>16)&0xff));
                  }
                  catch (Exception ex) { report(ex); }
        \\        return null;
        \\    }
        \\});
    }
    /*
    
    FUN Get_control_font_face({Control} C|ontrol_object) ==> STR, NATIVE :
		INT h|andle_control = C.Handle
		NATIVE @ "	RESULT = AL4_form.Do_Get_control_font_face(X_h);" .
    */
    public static String Do_Get_control_font_face(int X_H) {
        \\return get_property_string(new Callable<String>(){
        \\    @Override public String call() {
                  try {
                      View C = (View)AL4_form.All_descr.get(X_H).Jvc;
                      if (C instanceof TextView)
                          return ((TextView)C).getTypeface().toString();
                  }
                  catch (Exception ex) { report(ex); }
                  return "Arial";
        \\    }
        \\});
    }
    /*
    
    FUN Set_control_font_face(
    {Control} C|ontrol_object, STR Face|_set), NATIVE :
		INT h|andle_control = C.Handle
		NATIVE @ "	AL4_form.Do_Set_control_font_face(X_h, X_Face);" .
    */
    public static void Do_Set_control_font_face(int X_H, String X_Face) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      View C = (View)AL4_form.All_descr.get(X_H).Jvc;
                      if (C == null || !(C instanceof TextView)) 
                      	return 
                      	\\null
                      	;
                      ((TextView)C).setTypeface(
                          Typeface.create(X_Face, Typeface.NORMAL));
                  }
                  catch (Exception ex) { report(ex); }
        \\        return null;
        \\    }
        \\});
    }
    /*        
        
    FUN Get_control_font_size(
    {Control} C|ontrol_object) ==> REAL, NATIVE :
		INT h|andle_control = C.Handle
		NATIVE @ "	RESULT = AL4_form.Do_Get_control_font_size(X_h);" .
    */
    public static double Do_Get_control_font_size(int X_H) {
        \\return get_property_double(new Callable<Double>(){
        \\    @Override public Double call() {
                  try {
                      View C = (View)AL4_form.All_descr.get(X_H).Jvc;
                      if (!(C instanceof TextView)) return 10.0;
                      return 0.0 + ((TextView)C).getTextSize();
                  }
                  catch (Exception ex) { report(ex); }
                  return 0.0;
        \\    }
        \\});
    }
    /*

    FUN Set_control_font_size(
    {Control} C|ontrol_object, REAL Size|_set), NATIVE :
		INT h|andle_control = C.Handle
		NATIVE @ "	AL4_form.Do_Set_control_font_size(X_h, X_Size);" .
    */
    public static void Do_Set_control_font_size(int X_H, double X_Size) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      View C = (View)AL4_form.All_descr.get(X_H).Jvc;
                      if (C == null || !(C instanceof TextView) || X_Size <= 0)
                          return 
                          \\null
                          ;
                      ((TextView)C).setTextSize((float)X_Size);
                  }
                  catch (Exception ex) { report(ex); }
        \\        return null;
        \\    }
        \\});
    }
    /*
    
    FUN Get_control_font_styles(
    {Control} C|ontrol_object) ==> STR, NATIVE :
		INT h|andle_control = C.Handle
		CASE h == 0 ? ==> ;
		NATIVE @ "	RESULT = AL4_form.do_Get_control_font_styles(X_h);" .
		
    */
	public static String do_Get_control_font_styles(int X_H) {
       \\return get_property_string(new Callable<String>(){
       \\     @Override public String call() {
                  try {
                      String RESULT = "";
                      View C = (View)AL4_form.All_descr.get(X_H).Jvc;
                      if (!(C instanceof TextView)) return RESULT;
                      Typeface tf = ((TextView)C).getTypeface();
                      if (tf != null) {
	                      int fs = tf.getStyle();
	                      if ((fs & Typeface.BOLD) != 0) RESULT += 'B';
	                      if ((fs & Typeface.ITALIC) != 0) RESULT += 'I';
	                      //if ((fs & FontStyle.IsUnderline()) != 0) RESULT += 'U';
	                      //if (fs & FontStyle.IsStrikeout()) != 0) RESULT += 'S';
                      } 
                      return RESULT;
                  }
                  catch (Exception ex) { report(ex); }
                  return "";
       \\     }
       \\ });
	}    
    /*

    FUN Set_control_font_styles(
    {Control} C|ontrol_object, STR St|yles_string_B_U_I_S), NATIVE :
		INT h|andle_control = C.Handle
		CASE h == 0 ? ==> ;
		NATIVE @ "	AL4_form.do_Set_control_font_styles(X_h, X_St);" .
    */
 	public static void do_Set_control_font_styles(int X_H, String X_St) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      View C = (View)AL4_form.All_descr.get(X_H).Jvc;
                      if (!(C instanceof TextView))
                      	return
                      	\\null
                      	;
                      int fs = Typeface.NORMAL;
                      for (int i = 0; i < X_St.length(); i++)
                      {
                          switch (X_St.charAt(i))
                          {
                          case 'B': fs |= Typeface.BOLD; break;
                          case 'I': fs |= Typeface.ITALIC; break;
                          }
                      }
                      Typeface tf = ((TextView)C).getTypeface();
                      if (tf != null) {
	                      int old_fs = tf.getStyle();
	                      if (old_fs == fs)
	                      	return
	                      	\\null
	                      	;
                      }
                      ((TextView)C).setTypeface(Typeface.create(
                          ((TextView)C).getTypeface(), fs));
                  }
                  catch (Exception ex) { report(ex); }
        \\        return null;
        \\    }
        \\});
 	}
        
    /*  
        
    //FUN Get_control_font_attrs(
    //        INT H|andle_to_control,
    //        {Font}.{font_attr} A|ttributes_list[])
    //    :
    //    A[].Clear
    //    STR a|ttributes_list = Get_control_font_styles(H)
    //    CASE "B" IN a ? A[] << 'BOLD' ;
    //    CASE "I" IN a ? A[] << 'ITALIC' ; .
    

    FUNCTION List_fonts_installed(
    INT Op|tions_1Mono_2True, STR Names|_of_fonts[])
        :
        Names[].Clear
        CASE Op & FONTS_MONO_TYPE == 0 ?
        	 Names[] << "Droid Sans" << "Droid Serif" ;
        Names[] << "Droid Sans Mono" .
        
	// Show message modal (until user press OK)
	//-----------------------------------------
	
	FUN Show_message(
	INT H|andler_form, STR Text|_show), NATIVE :
		STR ok|_text_localizable = "OK"._OK
		NATIVE @
		"     AL4_form.Do_show_message(X_H, X_Text, X_ok);" .
	*/
	public static class Message_box {
        public boolean answer_yes;
        public boolean answered;
        public AlertDialog dlg;
        public Message_box(//View parent, 
        	String Title, String message, 
                String Yes, String No) {
            \\run_on_ui_thread(true, new Callable<Void>(){
            \\    @Override public Void call() {
                      try {
                          AlertDialog.Builder b = new AlertDialog.Builder(
                              context_activity)
                          .setTitle(Title)
                          .setMessage(message)
                          .setIcon(android.R.drawable.ic_dialog_alert)
                          .setPositiveButton(Yes,
                              new DialogInterface.OnClickListener() {
                                  public void onClick(
                                      DialogInterface dialog, int which) {
                                      answer_yes = true;
                                      answered = true;
                                  }
                               });
                          if (No != "")
                              b.setNegativeButton(No,
                                  new DialogInterface.OnClickListener() {
                                      public void onClick(
                                          DialogInterface dialog, int which) {
                                          dialog.dismiss();
                                          answered = true;
                                      }
                                  });
                          dlg = b.create();
                          dlg.show();
                      }
                      catch (Exception ex) { report(ex); }
            \\        return null;
            \\    }
            \\});
        }
    }
	
	public static void Do_show_message(int H, String T, String OK) {
		AL4_form form = H > 0 ? (AL4_form)AL4_form.All_descr.get(H).Jvc
							  : null;
		Message_box mDialog = new Message_box(
			form == null ? "message" : form.Caption, T,
			OK, "");
		//doModal(mDialog);
		doModal(new Callable<Boolean>(){
			@Override public Boolean call() {
				return mDialog.answered;
			}
		});
	}

	/*
	// Ask a question which requires an answer Yes or No
	//-------------------------------------------------
	
	FUN Message_box_yes_no(
	INT H|andler_form, STR Text|_show) ==> BOOL, NATIVE :
		STR yes|_text_localizable = "Yes"._Yes
		STR no|_text_localizable = "No"._No
		NATIVE @
		"    RESULT = AL4_form.Do_ask_yes_no(X_H, X_Text, X_yes, X_no);" .
	*/
	public static boolean Do_ask_yes_no(int H, String T, String Yes, String No)
	{
		AL4_form form = (AL4_form)AL4_form.All_descr.get(H).Jvc;
		Message_box mDialog = new Message_box(form.Caption, T, Yes, No);
		//doModal(mDialog);
		doModal(new Callable<Boolean>(){
			@Override public Boolean call() {
				return mDialog.answered;
			}
		});
		return mDialog.answer_yes;
	}
	

	public static boolean doModal(Callable<Boolean> is_finished)
	{
        \\return get_property_boolean(new Callable<Boolean>(){
        \\    @Override public Boolean call() {
                  try {
                      boolean mQuitModal = false;
                      Method mMsgQueueNextMethod = null;
                      Field mMsgTargetFiled = null;
			
                      Class<?> clsMsgQueue = null;
                      Class<?> clsMessage = null;
			
                      try {
                          clsMsgQueue = Class.forName("android.os.MessageQueue");
                      } catch (Exception e) { report(e); return false; }
                      try {
                          clsMessage = Class.forName("android.os.Message");
                      } catch (Exception e) { report(e); return false; }
                      try {
                          mMsgQueueNextMethod = clsMsgQueue.getDeclaredMethod(
                          "next", new Class[]{});
                      } catch (Exception e) { report(e); return false; }
					
                      mMsgQueueNextMethod.setAccessible(true);
                      try {
                          mMsgTargetFiled = clsMessage.getDeclaredField("target");
                      } catch (Exception e) { report(e); return false; }
					
                      mMsgTargetFiled.setAccessible(true);
					
                      MessageQueue queue = Looper.myQueue();
                      while (!mQuitModal) {
                          // call queue.next(), might block
                           Message msg = null;
                           try {
                               msg = (Message)mMsgQueueNextMethod.invoke(
                                  queue, new Object[]{});
                           } catch (Exception e) { report(e); }
						 
                           if (null != msg) {
                               Handler target = null;
                               try {
                                  target = (Handler)mMsgTargetFiled.get(msg);
                               } catch (Exception e) { report(e); }
							 
                               if (target == null) {
                               // No target is a magic identifier for the quit message.
                                  mQuitModal = true;
                               }
							 
                               target.dispatchMessage(msg);
                               msg.recycle();
                           }
                           if (is_finished.call()) mQuitModal = true;
                       }
                       return true;
                  }
                  catch (Exception ex) { report(ex); }
                  return false;
        \\    }
        \\});
	}
	
	public View last_clicked_view = null;
	public static float last_down_x;
	public static float last_down_y;
	public static long ticks_last_down = 0;
	
	public static Semaphore op_sema = new Semaphore(1, true);
	
	public static boolean operation_started(
	C_Form F, int op_code, Ref_obj control) {
		try {
		//AL4_system.Write("{:" + op_code + "}");
			if (!op_sema.tryAcquire()) {
				boolean ok = false;
				for (int i = 0; i < 10; i++) {
					Thread.sleep(10);
					if (op_sema.tryAcquire()) {
						ok = true;
						break;
					}
				}
				if (!ok) return false;
			}
		//AL4_system.WriteLine("locked!");
	        if (F.F_level_event > 1) {
	            op_sema.release();
	    //AL4_system.WriteLine("F.F_level_event==" + F.F_level_event +
	    //" ==> unlocked! (return false)");
	            return false;
	        }
			F.M_operation_started((byte)op_code, control);
			return true;
		}
		catch (Exception ex) { AL4_form.report(ex); }
		return false;
	}
	
	public static void operation_ended(C_Form F, int op_code) {
	//AL4_system.Write("{" + op_code + "#}");
    //AL4_system.WriteLine("operation_ended, op_locker state: " + op_locker +
    //" " + op_locker.isLocked());
		try {
			try {
				F.M_operation_ended((byte)op_code);
			}
			finally {
				op_sema.release();
			}
		}
		catch (Exception ex) { report(ex); }
	}
	
	public static void Set_control_events(Ref_obj X_CC, View C,
		boolean can_click) {
		
    //AL4_system.WriteLine("Set_control_events, X_CC=" + X_CC + ", C=" + C +
    //", can_click=" + can_click + "#####################################");
	
		Set_control_events(X_CC, C, can_click, false);
	}
	
	public static void Set_control_events(Ref_obj X_CC, View C,
		boolean can_click, boolean can_focus)
	{
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                  //AL4_system.WriteLine("--------------### " + X_CC.Obj.getClass().getName());
                      if (!(X_CC.Obj instanceof C_Control))
                      	return
                      	\\null
                      	;
                      C_Control CC = (C_Control)X_CC.Obj;
                  //AL4_system.WriteLine("CC=" + CC + " ################################");
                      Ref_obj contr = X_CC;
					
                  //AL4_system.WriteLine("C=" + C + ", setOnTouchListener ##############");
				
                      GestureDetector gDetector = new GestureDetector(context_activity,
                          new SingleTap());
			
                      C.setOnTouchListener(new View.OnTouchListener() {
                          @Override
                          public boolean onTouch(View v, MotionEvent event) {
                              boolean handled = false;
                              try {
                                  handled = do_onTouch(v, event, contr, CC, can_click, gDetector, can_focus);
                              }
                              catch(Exception Ex) { report(Ex); return false; }
                              return handled;
                          }
                      });
			        
				
                      if (can_focus) {
                  //AL4_system.WriteLine(CC.F_Alias + " can_focus=" + can_focus + ", setOnKeyListener ####");
                          if (C instanceof TextView) {
                              ATextWatcher tw = new ATextWatcher(X_CC);
                              ((TextView)C).addTextChangedListener(tw);
                              //AL4KeyListener kl = new AL4KeyListener(X_CC);
                              //((TextView)C).setFilters(new InputFilter[]{ kl });
                          }
                          C.setOnKeyListener(new View.OnKeyListener() {
                              public boolean onKey(View v, int keyCode, KeyEvent E) {
                                  boolean handled = false;
                                  int c = 0;
                                  try {
              //C_Log_html.M_Log_colored(0xFF, "onKey: " + keyCode +
              //" char=" + E.getUnicodeChar()  +
              //" action=" + E.getAction() + " sender is " + CC.F_Alias + '\n');
                                      boolean do_event = true;
                                      c = E.getUnicodeChar();
                                      C_Form F = (C_Form)CC.F_Form_.Obj;
                                      if (c == 10 &&
                                          E.getAction() == KeyEvent.ACTION_DOWN) {
                                          AL4_form form = (AL4_form)All_descr.get(F.F_Handle).Jvc;
                                          Ref_obj contr = X_CC;
                                          F.F_Key = AL4_object.Object_assign_hard(
                                          	F.F_Key, prepare_key(E, (char)10));
                                      }
                                      else if (c != 0 &&
                                          E.getAction() == KeyEvent.ACTION_DOWN) {
                                          AL4_form form = (AL4_form)All_descr.get(F.F_Handle).Jvc;
                                          Ref_obj contr = X_CC;
                                          F.F_Key = AL4_object.Object_assign_hard(
                                          	F.F_Key, prepare_key(E, (char)c));
                                      }
                                      else do_event = false;
                                      if (do_event) {
                                          if (operation_started(F, 17, CC.hard_link)) {
                                          //-------------------------------------------
                                              \\int r1 = run_on_background_wait(new Callable<Integer>(){
                                              \\    @Override public Integer call() {
                                              			int r1 = 0;
                                                        try {
                                                            try {
                                                                \\r1 = get_property_int(new Callable<Integer>(){
                                                                \\    @Override public Integer call() {
                                                                \\		  int r1 = 0;
                                                                          try {
                                                                              r1 = (int)F.M_key_press();
                                                                          }
                                                                          catch (Exception ex) {report(ex);}
                                                                \\		  return r1;
                                                                \\    }
                                                                \\});
                                                            }
                                                            finally {
                                                                operation_ended(F, 17);
                                                            }
                                                        }
                                                        catch(Exception ex) { report(ex); }
                                                        \\return r1;
                                              \\    }
                                              \\});
                                              if (r1 > 0) handled = true;
                                          //-------------------------------------------
                                          }
                                      }
                                  }
                                  catch (Exception ex2) { report(ex2); }
			                    
                                  //AL4_system.WriteLine("" + c + "[" + (char)c
                                  //+ "] on key listener retrn: " + handled);
			                    
                                  return handled;
                              }
                          });
                      }
			        
                  }
                  catch (Exception ex) { report(ex); }
        \\        return null;
        \\    }
        \\});
	//AL4_system.WriteLine("events set, return ###############################");
	}
	
	public static boolean do_onTouch(View v, MotionEvent event,
	Ref_obj contr, C_Control CC, boolean can_click, GestureDetector gDetector,
	boolean can_focus) throws Exception {
	
    	v.getParent().requestDisallowInterceptTouchEvent(true);
    	
        boolean is_click = can_click && gDetector.onTouchEvent(event);
        if (is_click) {
		    //******************************
		    C_Form F = (C_Form)CC.F_Form_.Obj;
		    if (F.F_level_event > 1) return true;
		    //******************************
        }
        boolean handled = false;
    //AL4_system.Write((is_click ? "*" : "") +
    //    ((event.getAction() == MotionEvent.ACTION_MOVE) ? "." :
    //        (event.getAction() == MotionEvent.ACTION_CANCEL) ? "X" :
    //            (event.getAction() == MotionEvent.ACTION_DOWN) ? "V"
    //                                                           : "^") );
        
        CC.F_stop_handling = false;
        C_Form F = (C_Form)CC.F_Form_.Obj;
        
        AL4_form form = (AL4_form)All_descr.get(F.F_Handle).Jvc;
        PointF prev_point = new PointF(
            form.Mouse_point.x, form.Mouse_point.y);
            
		int[] vXY = new int[2];     	
        v.getLocationInWindow(vXY);
        
        //int[] formXY = new int[2];
        //form.Form.getLocationInWindow(formXY);
        
        MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords();
        event.getPointerCoords(0, coords);
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
        	last_down_x = coords.x;
        	last_down_y = coords.y;
        }
        form.Mouse_point.x = coords.x + vXY[0];// - formXY[0]; 
        form.Mouse_point.y = coords.y + vXY[1];// - formXY[1]; 
        
//AL4_system.WriteLine("[" + CC.F_Alias + "]" +
//" control pos: x=" + vXY[0] + "; y=" + vXY[1] +
//" cp in pt: x=" + Pixels(vXY[0]) + "; y=" + Pixels(vXY[1]) +
//" touch pos: x=" + coords.x + "; y=" + coords.y + " fixed: x=" +
//form.Mouse_point.x + " ; y=" + form.Mouse_point.y +
//" in points: " + Pixels(form.Mouse_point.x) + "; " + Pixels(form.Mouse_point.y));
        
        form.Mouse_wheel_vertical = 0;
        form.Mouse_wheel_horizontal = 0;
			
//AL4_system.WriteLine("TOUCH [" + CC.F_Alias + "]" + is_click);
		boolean is_move = false;
		if (!is_click || event.getAction() == MotionEvent.ACTION_UP) {
			if (do_control_touch_actions(event, CC, form, v))
				return true;
			handled = CC.F_stop_handling;
		}
		
        if (!handled) {
        	handled = can_click && !(v instanceof TextView);
            if (contr != null) {
                if ((v instanceof EditText) && v.isEnabled() || can_focus) {
                	if (event.getAction() == MotionEvent.ACTION_UP) {
                		if (Math.abs(coords.x - last_down_x) +
                    		Math.abs(coords.y - last_down_y) <= 15) {
                        	boolean req = v.requestFocus();
		                       	if (req) show_keyboard();
                		}
                	}
                }
        	}
	        if (is_click) {
	            if (operation_started(F, 13, CC.hard_link)) {
	            //-------------------------------------------
                    \\run_on_background_thread(new Callable<Void>(){
                    \\    @Override public Void call() {
                              try {
                                  try { F.M_click(); }
                                  finally { operation_ended(F, 13); }
                              }
                              catch (Exception ex) { report(ex); }
                    \\        return null;
                    \\    }
                    \\});
	            //-------------------------------------------
	            }
	        }
	        if (!is_click || event.getAction() == MotionEvent.ACTION_UP
	        	|| event.getAction() == MotionEvent.ACTION_MOVE) {
	        	if (do_touch_actions(event, CC, F, form, prev_point))
	        		return true;
	        }
        }
        return handled;
    }
    
    public static boolean do_control_touch_actions(
    MotionEvent event, C_Control CC, AL4_form form, View v) throws Exception {
    	boolean is_move = false;
    	switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            form.last_clicked_view = v;
            form.Mouse_button = 1;
            CC.M_mouse_down();
            break; //LMB
        case MotionEvent.ACTION_UP:
            CC.M_mouse_up();
            form.Mouse_button = 0;
            break; //LMB released
        case MotionEvent.ACTION_MOVE:
            CC.M_mouse_move();
            is_move = true;
            break;
        case MotionEvent.ACTION_CANCEL:
			if (form.Dont_touch) return true;
//AL4_system.WriteLine("#############################################" +
//" ACTION_CANCEL");
        }
        boolean handled = CC.F_stop_handling;
        //_________________________________________________________
        // important! this prevents intercepting onTouch events by
        // parent scroll views, if panning is started or about to
        // start:
        if (!is_move || is_move && !form.Dont_touch)
        	form.Dont_touch = handled;
        return false;
	}
	
	public static FutureTask last_FuttureTask_down = null;
    
    public static boolean do_touch_actions(MotionEvent event, C_Control CC,
    C_Form F, AL4_form form, PointF prev_point) throws Exception {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
        //******************************
	    if (F.F_level_event > 1) return true;
	    //******************************

//AL4_system.WriteLine("vvvvvvvvvvvvv mouse down: " + F.F_level_event +
//(F.F_level_event > 0 ? " " + F.F_level_inc_on_event_kind : ""));
	     	FutureTask[] ft_wait = new FutureTask[1];
	        if (operation_started(F, 11, CC.hard_link)) {
	        //-------------------------------------------
                \\run_on_background_thread(ft_wait, new Callable<Void>(){
                \\    @Override public Void call() {
                          try {
                              try { F.M_mouse_down(); }
                              finally { operation_ended(F, 11); }
                          }
                          catch (Exception ex) { report(ex); }
                \\        return null;
                \\    }
                \\});
	        //-------------------------------------------
	        }
	        
	        if (SystemClock.uptimeMillis() - ticks_last_down <= 400) {
	        	ticks_last_down = 0;
	        	if (ft_wait[0] != null) {
		        	ft_wait[0].get(); //////////// wait for finishing last task
		        	ft_wait[0] = null;
	        	}
	            //if (F.F_level_event > 1) {
	            //    AL4_system.WriteLine("F.F_level_event > 1, " +
	            //    "F.F_level_inc_on_event_kind=" + F.F_level_inc_on_event_kind);
	            //}
	            if (operation_started(F, 13, CC.hard_link)) {
	            //-------------------------------------------
                    \\run_on_background_thread(new Callable<Void>(){
                    \\    @Override public Void call() {
                              try {
                                  try { F.M_mouse_double_click(); }
                                  finally { operation_ended(F, 13); }
                              }
                              catch (Exception ex) { report(ex); }
                    \\        return null;
                    \\    }
                    \\});
	            //-------------------------------------------
	            }
	        }
	        else ticks_last_down = SystemClock.uptimeMillis();
	        
	        last_FuttureTask_down = ft_wait[0];

            break;
        case MotionEvent.ACTION_UP:
		    //******************************
		    if (F.F_level_event > 1) return true;
		    //******************************
	        
			temp_file_write();
//AL4_system.WriteLine("--------------- last mouse down wait: " + last_FuttureTask_down);
			if (last_FuttureTask_down != null) {
				last_FuttureTask_down.get();
				last_FuttureTask_down = null;
			}
			
//AL4_system.WriteLine("^^^^^^^^^^^^^ mouse up: " + F.F_level_event +
//(F.F_level_event > 1 ? " " + F.F_level_inc_on_event_kind : ""));
            if (operation_started(F, 12, CC.hard_link)) {
            //-------------------------------------------
                \\run_on_background_thread(new Callable<Void>(){
                \\    @Override public Void call() {
                          try {
                              try { F.M_mouse_up(); }
                              finally { operation_ended(F, 12); }
                          }
                          catch (Exception ex) { report(ex); }
                \\        return null;
                \\    }
                \\});
            //-------------------------------------------
            }
            break;
        case MotionEvent.ACTION_MOVE:
//?{Form}.mouse_wheel
            if (event.getPointerCount() == 2) {
                if (Math.abs(form.Mouse_point.y - prev_point.y) >=
                    Points(2))
                    form.Mouse_wheel_vertical =
                        Points(form.Mouse_point.y - prev_point.y) / 2;
				
                if (Math.abs(form.Mouse_point.y - prev_point.y) >=
                    Points(2))
                    form.Mouse_wheel_vertical =
                        Points(form.Mouse_point.y - prev_point.y) / 2;
						
                if (form.Mouse_wheel_vertical != 0 ||
                    form.Mouse_wheel_horizontal != 0) {
                    if (operation_started(F, 14, CC.hard_link)) {
                    //-------------------------------------------
                        \\run_on_background_thread(new Callable<Void>(){
                        \\    @Override public Void call() {
                                  try {
                                      try { F.M_mouse_wheel(); }
                                      finally { operation_ended(F, 14); }
                                  }
                                  catch (Exception ex) { report(ex); }
                        \\        return null;
                        \\    }
                        \\});
                    //-------------------------------------------
                    }
                }
            }
//.
//?{Form}.mouse_move
            {
                if (operation_started(F, 10, CC.hard_link)) {
                //-------------------------------------------
                    \\run_on_background_wait(new Callable<Integer>(){
                    \\    @Override public Integer call() {
                              try {
                                  try { F.M_mouse_move(); }
                                  finally { operation_ended(F, 10);
                                  //AL4_system.WriteLine("--- ended");
                                  }
                              }
                              catch (Exception ex) { report(ex); }
                    \\        return 0;
                    \\    }
                    \\});
                //-------------------------------------------
                }
            }
//.
            break;
        case MotionEvent.ACTION_CANCEL:
			if (form.Dont_touch) return true;
        }
        return false;
    }
    
	public static class ATextWatcher implements TextWatcher {
	
		public Ref_obj X_Control;
	    
	    public ATextWatcher(Ref_obj X_CC) {
	    	X_Control = X_CC;
	    }
	    
    	@Override
    	public void beforeTextChanged(CharSequence seq, int i, int i1, int i2) {
    	}
    	
    	@Override
    	public void onTextChanged(CharSequence seq, int i, int i1, int i2) {
            \\run_on_ui_thread(true, new Callable<Void>(){
            \\    @Override public Void call() {
                      try {
                          C_Control CC = (C_Control)X_Control.Obj;
      //AL4_system.WriteLine("changing: " + CC.F_Alias);
                          C_Form F = (C_Form)CC.F_Form_.Obj;
                          AL4_form form = (AL4_form)AL4_form.All_descr.get(F.F_Handle).Jvc;
                          if (operation_started(F, 5, CC.hard_link)) {
                          //------------------------------------------
                              try {
                                  F.M_Notify_value_change(X_Control);
                                  //F.M_value_change();
                              } finally {
                                  operation_ended(F, 5);
                              }
                              //F.M_Any_change(X_Control);
                          //------------------------------------------
                          }
                      }
                      catch (Exception ex) { report(ex); }
            \\        return null;
            \\    }
            \\});
    	}
    	
		@Override
    	public void afterTextChanged(Editable editable) {
	//AL4_system.WriteLine("CHANGED.");
    	}
    	
	}
	

    public static C_Form.St_key_info prepare_key(KeyEvent E, char ch)
    {
        C_Form.St_key_info info = (C_Form.St_key_info)
        							C_Form.St_key_info.New().Obj;
        info.f_Char = E != null 
        				? "" + (char)E.getUnicodeChar()
        				: "" + ch;
        if (E != null) {
	        if (E.isAltPressed()) info.f_Alt = true;
	        if (E.isCtrlPressed()) info.f_Ctrl = true;
	        if (E.isShiftPressed()) info.f_Shift = true;
	        if (E.isFunctionPressed()) info.f_Win = true;
	        int Key = (int)E.getKeyCode();
        	info.f_Special = Key;
        	info.f_Caps = E.isCapsLockOn();
        }
        return info;
    }
   
	public static void show_keyboard() {
		InputMethodManager imm = (InputMethodManager) context_activity.getSystemService(
			Activity.INPUT_METHOD_SERVICE);
		//AL4_system.WriteLine("FORCE keyboard show " + imm.isActive());
		//if (!imm.isActive()) { -- with this check, does not work
			imm.toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY);
		//}
	}
	
	private static class SingleTap extends SimpleOnGestureListener {
		@Override
		public boolean onSingleTapUp(MotionEvent ev) { return true; }
	}

    public static AL4Column Get_parent_for_new_control(int H) {
        try {
            AL4_form f = (AL4_form)AL4_form.All_descr.get(H).Jvc;
            if (f == null) return null;
            if (f.HCurrent_column_handle == 0) {
                C_Form F = (C_Form)AL4_form.All_descr.get(H).Ref.Obj;
                F.M_initial_column();
            }
            AL4Column P = (AL4Column)AL4_form.All_descr.get(
                f.HCurrent_column_handle).Jvc;
            return P;
        }
        catch (Exception ex) { report(ex); return null; }
    }
    
    static int delta_width = 4;
    public static void adjust_control_size_position(AL4Column Col, View A) {
    }
    
    public static void adjust_control_1(AL4Column Col, View A) {
    }
    
    /*
    
    FUN Control_click(
    {Control} C|ontrol_which_click_should_be_handled)
    	: C.Form_.click .
    
    */
    
    
    
    /*
    
    FUNCTION Begin_animation(
        INT H|andle_control, INT Count|_ticks, INT Interval|_ms ), NATIVE : @
        "AL4_form.do_begin_animation(X_H, X_Count, X_Interval);" .
    */
    
    public static void do_begin_animation(int X_H, int X_Count, int X_Interval)
    {
    	View C = (View)AL4_form.All_descr.get(X_H).Jvc;
    	AL4Column col = Get_parent_column(C);
    	AL4_form F = col.Form_;
    	for (int i = F.Control_timers.size() - 1; i > 0; i--)
    	{
    		Animation_timer a = F.Control_timers.get(i);
    		if (a.Control_handle == X_H)
    		{
    			a.Counter = 0;
    			a.Last_counter = X_Count;
    			//a.Interval = X_Interval; ????????????????????????????????????
    			return;
    		}
    	}
    	 new AL4_form.Animation_timer(X_H, X_Count, X_Interval);
    }
    
    public ArrayList<Animation_timer> Control_timers = 
                                new ArrayList<Animation_timer>();
                                
    /*
    FUNCTION Capture_mouse( INT H|andle_control ), NATIVE :
    @   "" .
        
    FUNCTION Release_mouse( INT H|andle_control ), NATIVE :
    @   "" .
    
	FUN Set_control_anchor_bottom(
	{Control} C|ontrol_changed, BOOL A|nchor_bottom), NATIVE : @ 
		"//do not remove this function, it is necessary for interpreting" .
		
	FUN Invalidate_form(INT H|andle_form): .		

	FUNCTION Invalidate_control(INT H|andle_control),
		NATIVE :
		"	AL4_form.Do_Invalidate_control(X_H);" .
	*/
	public static void Do_Invalidate_control(int X_H) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      View C = (View)AL4_form.All_descr.get(X_H).Jvc;
                      C.invalidate();
                  }
                  catch (Exception ex) { report(ex); }
        \\        return null;
        \\    }
        \\});
 	}   
    
    
	//------------------------------------------------------- L A B E L

	/*
	// Create label control, return integer descriptor to it
	//------------------------------------------------------
	FUN Create_label({Control} L|abel_control) ==> INT :
		RESULT = do_create_label(L.Form_.Handle, L) .

	FUN do_create_label(INT P|arent_handle,
		{Control} L|abel_create) ==> INT, NATIVE :
		"     RESULT = AL4_form.Do_Create_label(X_P, X_L);" .
	*/
	public static int Do_Create_label(int H, Ref_obj X_L) {
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                      AL4Column P = Get_parent_for_new_control(H);
					
                      //AL4_system.WriteLine("******************************************\n" +
                      //"H=" + H + "P=" + P + '\n');
                      TextView L = new TextView(context_activity);
			        
                      int Result = AL4_form.Alloc_descriptor(L, X_L);
					
                      if (P.Horizontal || !P.No_labels)
                          P.addView(L);
                      else {
                          TableRow row = new TableRow(context_activity);
                          row.setLayoutParams(new LayoutParams(
                              LayoutParams.MATCH_PARENT,
                              LayoutParams.WRAP_CONTENT));
							
                          L.setLayoutParams(new TableRow.LayoutParams(
                              LayoutParams.MATCH_PARENT,
                              LayoutParams.WRAP_CONTENT));
						
                          row.addView(L);
                          P.table_content.addView(row);
                          P.prev_label_row = row;
                      }
			
                      //adjust_control_size_position(P, L);
                      Set_control_events(X_L, L, true);
					
                      //AL4_system.WriteLine("label added");
					
                      return Result;
                  }
                  catch (Exception ex) { report(ex); }
                  return 0;
        \\    }
        \\});
	}

	//---------------------------------------------------- B U T T O N

	/*
	// Create button control, return descriptor
	//------------------------------------------
	FUN Create_button({Control} B|utton_control) ==> INT :
		RESULT = do_create_button(B.Form_.Handle, B) 
		//DEBUG: << "button created, RESULT=" RESULT.S #NL ;
		.

	FUN do_create_button(INT F|orm_handle, 
		{Control} B|utton_create) ==> INT, NATIVE :
		"     RESULT = AL4_form.Do_Create_button(X_F, X_B);" .
	*/
	public static int add_control_multi_line(int H, View C, Ref_obj X_C) {
		return add_control_multi_line(H, C, X_C, false);
	} 
	
	public static int add_control_multi_line(int H, View C, Ref_obj X_C,
		boolean match_parent) {
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                      AL4Column P = Get_parent_for_new_control(H);
                      int Result = AL4_form.Alloc_descriptor(C, X_C);
			        
                      if (P.Horizontal || P.No_labels)
                          P.addView(C);
                      else {
                          TableRow.LayoutParams cell_params = new TableRow.LayoutParams(
                              LayoutParams.MATCH_PARENT,
                              match_parent ? LayoutParams.MATCH_PARENT
                                           : LayoutParams.WRAP_CONTENT);
                          if (!P.No_labels) cell_params.span = 2;
                          TableRow row = new TableRow(context_activity);
                          row.setLayoutParams(new LayoutParams(
                              LayoutParams.MATCH_PARENT,
                              match_parent ? LayoutParams.MATCH_PARENT
                                           : LayoutParams.WRAP_CONTENT));
                          P.table_content.addView(row);
                          P.prev_label_row = null;
                          C.setLayoutParams(cell_params);
                          row.addView(C);
                      }
                      return Result;
                  }
                  catch (Exception ex) { report(ex); }
                  return 0;
        \\    }
        \\});
	}
	
	public static int add_control_single_line(int H, View C, Ref_obj X_C) { 
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                      AL4Column P = Get_parent_for_new_control(H);
					
                      int Result = AL4_form.Alloc_descriptor(C, X_C);
                  //AL4_system.WriteLine("adding control to column " + P.Handle +
                  //    " Result = " + Result);
			        
                      if (P.Horizontal || P.No_labels)
                          P.addView(C);
                      else {
                          TableRow.LayoutParams cell_params = new TableRow.LayoutParams(
                              LayoutParams.MATCH_PARENT,
                              LayoutParams.WRAP_CONTENT);
                          TableRow row;
                          if (P.prev_label_row != null && !P.No_labels) {
                              row = P.prev_label_row;
                              //AL4_system.WriteLine("adding button right to label");
                          }
                          else {
                              //AL4_system.WriteLine("adding button span=2");
							
                              row = new TableRow(context_activity);
                              row.setLayoutParams(new LayoutParams(
                              LayoutParams.MATCH_PARENT,
                              LayoutParams.WRAP_CONTENT));
							
                              if (!P.No_labels) cell_params.span = 2;
                              P.table_content.addView(row);
                          }
                          P.prev_label_row = null;
                          C.setLayoutParams(cell_params);
                          row.addView(C);
                      }
                      P.Child_controls.add(X_C);
                      return Result;
                  }
                  catch (Exception ex) { report(ex); }
                  return 0;
        \\    }
        \\});
	}
	
	public static int Do_Create_button(int H, Ref_obj X_B)
	{
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                      Button B = new Button(context_activity);
                      int Result = add_control_single_line(H, B, X_B);
			
                      //AL4Column P = Get_parent_for_new_control(H);
                      //adjust_control_size_position(P, B);
                      Set_control_events(X_B, B, true);
					
                      //AL4_system.WriteLine("button added");
                      return Result;
                  }
                  catch (Exception ex2) { report(ex2); }
                  return 0;
        \\    }
        \\});
	}
    
    public Button Default_button;
    public Button Cancel_button;

    /*
    
    FUN Set_form_default_button(
    INT H|andle_form, INT B|utton_handle), NATIVE :
		"	AL4_form.Do_Set_form_default_button(X_H, X_B);" .
    */
    public static void Do_Set_form_default_button(int X_H, int X_B) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      AL4_form form = (AL4_form)AL4_form.All_descr.get(X_H).Jvc;
                      Button b = (Button)AL4_form.All_descr.get(X_B).Jvc;
                      form.Default_button = b;
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
    }
    
    /*
    
    FUN Set_form_cancel_button(
    INT H|andle_form, INT B|utton_handle), NATIVE :
		"	AL4_form.Do_Set_form_cancel_button(X_H, X_B);" .
    */
    public static void Do_Set_form_cancel_button(int X_H, int X_B) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      AL4_form form = (AL4_form)AL4_form.All_descr.get(X_H).Jvc;
                      Button b = (Button)AL4_form.All_descr.get(X_B).Jvc;
                      form.Cancel_button = b;
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
    }
    
	//------------------------------------------------- C H E C K B O X

	/*
	// Create checkbox, return descriptor
	//-----------------------------------
	FUN Create_checkbox({Control} C|heckbox_control) ==> INT :
		RESULT = do_create_checkbox(C.Form_.Handle, C) .

	FUN do_create_checkbox(INT F|orm_handle,
		{Control} C|checkbox_create) ==> INT, NATIVE :
		"     RESULT = AL4_form.Do_Create_checkbox(X_F, X_C);" .
	*/
	public static int Do_Create_checkbox(int H, Ref_obj X_C)
	{
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                      CheckBox C = new CheckBox(context_activity);
                      int Result = add_control_single_line(H, C, X_C);
			        
                      //adjust_control_size_position(P, C);
                      Set_control_events(X_C, C, false);
                      //C.addItemListener(P.Form_.Form_item_listener);
                      //C.addChangeListener(P.Form_.Form_change_listener);
                      return Result;
                  }
                  catch (Exception ex) { report(ex); }
                  return 0;
        \\    }
        \\});
	}

	/*
	// Return TRUE if checkbox is checked
	//-----------------------------------
	
	FUN Get_checkbox_checked(
	{Control} C|ontrol_object) ==> BOOL, NATIVE :
		INT h|andle_control = C.Handle
		NATIVE @ "    RESULT = AL4_form.Do_Get_checkbox_checked(X_h);" .
	*/
	public static boolean Do_Get_checkbox_checked(int H)
	{
        \\return get_property_boolean(new Callable<Boolean>() {
        \\        @Override public Boolean call() {
                     try {
                          CheckBox C = (CheckBox)AL4_form.All_descr.get(H).Jvc;
                          return C.isChecked();
                     }
                     catch (Exception ex2) { report(ex2); }
                     return false;
        \\        }
        \\});
	}

	/*
	// Set checkbox state (TRUE - checked, FALSE - unchecked)
	//-------------------------------------------------------
	
	FUN Set_checkbox_checked(
	{Control} C|ontrol_object, BOOL V|alue_checked), NATIVE :
		INT h|andle_control = C.Handle
		NATIVE @ "    AL4_form.Do_Set_checkbox_checked(X_h, X_V);" .
	*/
	public static void Do_Set_checkbox_checked(int H, boolean X_V)
	{
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      CheckBox C = (CheckBox)AL4_form.All_descr.get(H).Jvc;
                      C.setChecked(X_V);
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
	}

	/*
	// Get checkbox text 
	//-------------------------------------------------------
	
	FUN Get_checkbox_text(
	INT C|heckbox_handle) ==> STR, NATIVE :
		"	RESULT = AL4_form.Do_Get_checkbox_text(X_C);" .
	*/
	public static String Do_Get_checkbox_text(int X_C) {
        \\return get_property_string(new Callable<String>(){
        \\    @Override public String call() {
                  try {
                       CheckBox cb = (CheckBox)AL4_form.All_descr.get(X_C).Jvc;
                       return cb.getText().toString();
                  }
                  catch (Exception ex) { report(ex); }
                  return "";
        \\    }
        \\});
	}
   	/*
    // Set checkbox text 
	//-------------------------------------------------------
	
	FUN Set_checkbox_text(INT C|heckbox_handle,
		STR T|ext_set), NATIVE :
		"	AL4_form.Do_Set_checkbox_text(X_C, X_T);" .
	*/
	public static void Do_Set_checkbox_text(int X_C, String X_T) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                       CheckBox cb = (CheckBox)AL4_form.All_descr.get(X_C).Jvc;
                       cb.setText(X_T);
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
	}

	//------------------------------------------------------ E D I T

	/*
	// Create edit control, return descriptor
	//---------------------------------------
	
	FUN Create_edit(
        {Control} E|dit_control,
        STR Password|_char,
        BOOL RO||Read_only) ==> INT, NATIVE
        :
        INT form|_handle = E.Form_.Handle
        STR options|_on_create = E.{Edit}.options
        NATIVE @
		"RESULT = AL4_form.Do_Create_edit("
		"	X_form, X_E, X_Password, X_RO, X_options);" .
	*/
	public static void colors_like_for_button(TextView E) {
		int[] attrs = {
			android.R.attr.colorButtonNormal,
			android.R.attr.editTextColor };
		Resources.Theme theme = context_activity.getTheme();
		TypedArray ta = theme.obtainStyledAttributes(attrs);
		
		int back = ta.getColor(0, 0);
		E.setBackgroundColor(back);
		
		int fore = ta.getColor(1, 0);
		E.setTextColor(fore);
	}
	
	public static void set_edit_events(Ref_obj X_E, TextView V, boolean Read_only) {
		V.setOnEditorActionListener(new OnEditorActionListener(){
			@Override
			public boolean onEditorAction(TextView v, int action, KeyEvent ev) {
		//////////////////////////////////////////////////////////////
		//AL4_system.WriteLine("onEditorAction: " + action + " of " + v);
		//////////////////////////////////////////////////////////////
				if (action == EditorInfo.IME_ACTION_DONE ||
					action == EditorInfo.IME_NULL) {
					v.clearFocus();
					v.setSelected(false);
		////////////////////////////////////////////
		//AL4_system.WriteLine("clear focus on " + v);
		////////////////////////////////////////////
					return true;
				}
				return false;
			}
		});
	}
	
	public static int Do_Create_edit(int H, Ref_obj X_E, String X_Password,
        boolean X_Readonly, String X_options)
	{
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                      TextView E = X_Readonly
                          ? new TextView(context_activity)
                          : new EditText(context_activity);
                      int Result = add_control_single_line(H, E, X_E);
                      E.setSingleLine(true);
					
                      if (X_Readonly) colors_like_for_button(E);
                      set_edit_events(X_E, E, X_Readonly);
					
                      if (!X_Password.equals("")) {
                          char echo = X_Password.charAt(0);
                          E.setInputType(InputType.TYPE_CLASS_TEXT
                          | InputType.TYPE_TEXT_VARIATION_PASSWORD);
                      }
                      else if (X_options.contains("N")) {
                      	  E.setInputType(InputType.TYPE_CLASS_NUMBER);
                      }
                      else if (X_options.contains("P")) {
                      	  E.setInputType(InputType.TYPE_CLASS_PHONE);
                      }
                      else if (!X_options.contains("S")) {
                      	  E.setInputType(InputType.TYPE_NULL);
                      }
			        
                      //adjust_control_size_position(P, E);
                      Set_control_events(X_E, E, true, true);
                      //E.addTextListener(P.Form_.Form_change_listener);
                      return Result;
                  }
                  catch (Exception ex) { report(ex); }
                  return 0;
        \\    }
        \\});
	}

	/*
	// Get edit selection text
	//------------------------------
	
	FUN Get_edit_selection(INT E|dit_control) ==> STR, NATIVE :
		"    RESULT = AL4_form.Do_Get_edit_selection(X_E);" .
	*/
	public static String Do_Get_edit_selection(int H)
	{
        \\return get_property_string(new Callable<String>(){
        \\    @Override public String call() {
                  try {
                      EditText T = (EditText)AL4_form.All_descr.get(H).Jvc;
                      if (!T.hasSelection()) return "";
                      return T.getText().subSequence(
                          T.getSelectionStart(), T.getSelectionEnd()).toString();
                  }
                  catch (Exception ex) { report(ex); }
                  return "";
        \\    }
        \\});
	}

    /*
    // Get/set edit selection range
    //------------------------------
    
    FUN Get_edit_selection_start(
    INT E|dit_control) ==> INT, NATIVE :
		"	RESULT = AL4_form.Do_Get_edit_selection_start(X_E);" .
    */
    public static int Do_Get_edit_selection_start(int X_E) {
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                      EditText T = (EditText)AL4_form.All_descr.get(X_E).Jvc;
                      return T.getSelectionStart();
                  }
                  catch (Exception ex) { report(ex); }
                  return 0;
        \\    }
        \\});
    }
    /*
    
    FUN Get_edit_selection_length(
    INT E|dit_control) ==> INT, NATIVE :
		"	RESULT = AL4_form.Do_Get_edit_selection_length(X_E);" .
    */
    public static int Do_Get_edit_selection_length(int X_E) {
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                      EditText T = (EditText)AL4_form.All_descr.get(X_E).Jvc;
                      return T.getSelectionEnd() - T.getSelectionStart();
                  }
                  catch (Exception ex) { report(ex); }
                  return 0;
        \\    }
        \\});
    }
    
    /*
    
    //FUN IMax|imum_of_2_integers(
    //INT A|_parameter, INT B|_parameter) ==> INT
    //    :
    //    CASE A > B ? RESULT = A ==> ;
    //    RESULT = B .
    
    FUN Set_edit_selection_range(
    INT E|dit_control, INT Start|_selection, INT Length|_selection), NATIVE :
   		INT slen|gth_selection = IMax(0, Length)
   	NATIVE @
		"	AL4_form.Do_Set_edit_selection_range(X_E, X_Start, X_slen);" .
    */
    public static void Do_Set_edit_selection_range(int X_E, int X_Start, 
    	int X_Length) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      EditText T = (EditText)AL4_form.All_descr.get(X_E).Jvc;
                      T.setSelection(X_Start, X_Start + X_Length);
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
    }
        
    /*
	// Replace edit selection with another text
	//-----------------------------------------
	
	FUN Set_edit_selection(
	INT E|dit_control, STR Text|_replace_selection), NATIVE :
		"    AL4_form.Do_Set_edit_selection(X_E, X_Text);" .
	*/
	public static void Do_Set_edit_selection(int H, String X_Text)
	{
//?{Edit}
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      EditText T = (EditText)AL4_form.All_descr.get(H).Jvc;
                      C_Edit C_T = (C_Edit)AL4_form.All_descr.get(H).Ref.Obj;
                      String old = T.getText().toString();
                      String set = old.substring(0, T.getSelectionStart()) + X_Text +
                          old.substring(T.getSelectionEnd(), old.length()-1);
                      T.setText(set, C_T.F_read_only ?
                          TextView.BufferType.NORMAL : TextView.BufferType.EDITABLE);
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
//.
	}

	/*
	// Set edit maximal length
	//------------------------
	FUN Set_edit_max_len(INT E|dit_control, INT V|alue_max_len),
		NATIVE :
		"    AL4_form.Do_Set_edit_max_len(X_E, X_V);" .
	*/
	public static void Do_Set_edit_max_len(int H, int X_V)
	{
	}

	//------------------------------------------------------- M E M O

	/*
	// Create memo control, return descriptor
	//---------------------------------------
	FUN Create_memo(
		{Control} M|emo_control,
		STR RVHsC|_Read_only | Vertical_scroll | Horizontal_scroll
			| no_suggestions | Caret_enter) ==> INT, NATIVE
		:
    	INT form|_handle = M.Form_.Handle
    	BOOL ronly||read_only = "R" IN RVHsC
    	BOOL vert|ical_scroll = "V" IN RVHsC
    	BOOL hor|izontal_scroll = "H" IN RVHsC
    	BOOL no_suggestions = "s" IN RVHsC
    	BOOL no_caret|_return_enter = "c" IN RVHsC
    NATIVE @
    "   RESULT = AL4_form.Do_Create_memo(X_form, X_M, "
    "       X_ronly, !X_vert, !X_hor, X_no_suggestions, X_no_caret);" .
	*/
	public static int Do_Create_memo(int H, Ref_obj X_M, boolean X_Readonly,
        boolean NoH, boolean NoV, boolean NoSugg, boolean NoCaretRet)
	{
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                      TextView M = X_Readonly
                           ? new TextView(context_activity)
                           : new EditText(context_activity);
                      if (NoSugg)
	                      M.setInputType(InputType.TYPE_NULL);
                              //InputType.TYPE_CLASS_TEXT
                              //| InputType.TYPE_TEXT_FLAG_MULTI_LINE
	                          //| InputType.TYPE_TEXT_VARIATION_LONG_MESSAGE
	                          //);
                      
                      //M.setMinLines(1);
                      //M.setMaxLines(1000000);
                      //M.setImeOptions(EditorInfo.IME_FLAG_NO_ENTER_ACTION);
                      //if (!NoV) {
                      //    M.setVerticalScrollBarEnabled(true);
                      //    M.setMovementMethod(
                      //        ScrollingMovementMethod.getInstance());
                      //}
                      M.setGravity(Gravity.TOP);
			        
                      int Result = add_control_multi_line(H, M, X_M);
					
                      if (X_Readonly) {
                          colors_like_for_button(M);
                          Display display = context_activity.getWindowManager()
                                  .getDefaultDisplay();
                          Point size = new Point();
                          display.getSize(size);
                          int width = size.x;
                          int height = size.y;
                          int m = height;
                          if (m > width) m = width;
                          M.setHeight(m / 2);
                      }
                      set_edit_events(X_M, M, X_Readonly);
                      M.setMovementMethod(new ArrowKeyMovementMethod());
                      Set_control_events(X_M, M, true, true);
					
                      if (!X_Readonly && !NoCaretRet)
                      M.setOnEditorActionListener(
                          new TextView.OnEditorActionListener() {
                              @Override
                              public boolean onEditorAction(
                                      TextView v,
                                      int actionId,
                                      KeyEvent keyEvent) {
                                  if (actionId == EditorInfo.IME_ACTION_DONE) {
                                      String was = v.getText().toString();
                                      int where = v.getSelectionStart() >= 0 ?
                                          v.getSelectionStart() : 0;
                                      StringBuilder will = new StringBuilder(was);
                                      will.insert(where, "" + (char)10);
                                      v.setText(will.toString());
                                      ((EditText)v).setSelection(where+1);
                                      return true;
                                  }
                                  return false;
                              }
                          });
				    
                      return Result;
                  }
                  catch (Exception ex) { report(ex); }
                  return 0;
        \\    }
        \\});
	}
    
   
	/*
	// Memo in Java awt does not provide lines in API.
	//----------------------------------------------
	
	FUN Memo_supports_lines ==> BOOL : RESULT = FALSE .
	*/

	/*
	// Return memo line by index - not supported
	//--------------------------
	
	FUN Get_memo_item|_dummy(INT M|emo_control_dummy, 
        INT Row|_index_dummy) ==> STR : .
	*/

	/*
	// Set memo line by index -- not supported
	//-----------------------
	
	FUN Set_memo_item|_dummy( INT M|emo_control_dummy, 
                              INT Row|_index_dummy,
                              STR V|alue_set_dummy) : .
	*/

	/*
	// Return count lines in memo -- not supported
	//---------------------------
	
	FUN Get_memo_count_lines|_dummy(
	INT M|emo_control_dummy) ==> INT : .
	*/

	/*
	// Get memo selection text
	//------------------------
	
	FUN Get_memo_selection(INT M|emo_control) ==> STR,
	NATIVE :
		"    RESULT = AL4_form.Do_Get_edit_selection(X_M);" .
		
	// Replace memo selection with another text
	//-----------------------------------------
	
	FUN Set_memo_selection(INT M|emo_control, 
		STR Text|_replacing_selection), NATIVE :
		"    AL4_form.Do_Set_memo_selection(X_M, X_Text);" .
	*/
	public static void Do_Set_memo_selection(int H, String X_Text)
	{
//?{Memo}
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      EditText M = (EditText)AL4_form.All_descr.get(H).Jvc;
                      C_Memo C_M = (C_Memo)AL4_form.All_descr.get(H).Ref.Obj;
                      String txt = M.getText().toString();
                      M.setText( txt.substring(0, M.getSelectionStart()) + X_Text +
                          txt.substring(M.getSelectionEnd()+1),
                          C_M.F_read_only
                              ? TextView.BufferType.NORMAL
                              : TextView.BufferType.EDITABLE );
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
//.
	}

	/*
	// Return FALSE indicating that text limit is not supported
	//---------------------------
	FUN Memo_supports_text_limit ==> BOOL : .
	*/

	/*
	// Set memo maximal length -- not supported
	//---------------------------
	FUN Set_memo_max_len|_dummy( INT M|emo_control_dummy, 
                                 INT V|alue_max_len) : .
	*/
    
    /*
    // Get memo range selection
    //---------------------------
    
    FUNCTION Get_memo_range_sel(
        	INT M|emo_control) ==> {Control}.{from_to}
        	:
			RESULT = {from_to}(From = get_memo_sel(M, TRUE))
			RESULT.To = get_memo_sel(M, FALSE)
			.
        FUN get_memo_sel(
        	INT H|andle_memo,
        	BOOL Start|_otherwise_Length) ==> INT, NATIVE : @
        "    RESULT = AL4_form.Do_Get_memo_rangle_sel(X_H, X_Start);" .
    */
    public static int Do_Get_memo_rangle_sel(int H, boolean X_Start)
    {
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                      EditText M = (EditText)AL4_form.All_descr.get(H).Jvc;
                      if (X_Start) return M.getSelectionStart();
                      else return M.getSelectionEnd();
                  }
                  catch (Exception ex) { report(ex); }
                  return 0;
        \\    }
        \\});
    }

    /*
    // Set memo range selection
    //---------------------------
    
    FUN Set_memo_range_sel(
    INT M|emo_control, {from_to} R|ange_selection) 
        :
        do_Set_memo_range_sel(M, R.Line_from, R.Line_to, R.From, R.To) .
    FUN do_Set_memo_range_sel(INT M|emo_control,
        INT Line_fr|om_or_0, INT Line_to|_or_0,
        INT Fr|om_character, INT To|_character), NATIVE : @
        "	AL4_form.do_Set_memo_range_sel(X_M, X_Line_fr, X_Line_to,"
        "		X_Fr, X_To);" .
        
    FUNCTION Get_memo_entire_text_shown(
		{Control} M|emo_control) ==> BOOL: .
        
    */
    public static void do_Set_memo_range_sel(int X_M, 
    int X_Line_fr, int X_Line_to, int X_Fr, int X_To) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      EditText M = (EditText)AL4_form.All_descr.get(X_M).Jvc;
                      M.setSelection(X_Fr, X_To);
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
    }
    /*
	//--------------------------------------------- L I S T B O X
    
    // Create listbox control, return descriptor. Only detailed view is possible.
    //----------------------------------------------------------------------------
    
    FUN Create_listbox({Control} L|istbox_control,
        BOOL Multi|select) ==> INT
        :
        RESULT = do_create_listbox(L.Form_.Handle, L, Multi) .

    FUN do_create_listbox(INT F|orm_handle, {Control} L|istbox_create, 
        BOOL Multi|select) ==> INT, NATIVE :
        "     RESULT = AL4_form.Do_Create_listbox(X_F, X_L, X_Multi);" .
    */
    public static class AL4_ListView extends ListView {
    	public int item_selected = -1;
    	
    	public AL4_ListView(Activity a) { super(a);
    	}
    
    }
    
	public static int Do_Create_listbox(int H, Ref_obj X_L,
        Boolean X_Multiselect)
	{
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                      AL4_ListView L = new AL4_ListView(context_activity);
                      ArrayList<String> a = new ArrayList<String>();
                      ArrayAdapter<String> aa = new ArrayAdapter<String>(context_activity,
                          X_Multiselect
                          ? android.R.layout.simple_list_item_multiple_choice
                          //: android.R.layout.simple_list_item_single_choice,
                          : android.R.layout.simple_list_item_1,
                          a);
                      L.setAdapter(aa);
			        
                      if (X_Multiselect) L.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
			        
                      int Result = add_control_multi_line(H, L, X_L, true);

                      AL4_form.Set_control_events(X_L, L, false);
                      //L.addItemListener(P.Form_.Form_item_listener);
			        
                      L.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                          @Override
                          public void onItemSelected(AdapterView<?> parent, View view,
                              int position, long id) {
                              call_selected_event(X_L, L);
                          }
			        	
                          @Override
                          public void onNothingSelected(AdapterView<?> parent) {
                              call_selected_event(X_L, L);
                          }
                      });
			        
                      L.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                          @Override
                          public void onItemClick(AdapterView<?> parent, View view,
                              int position, long id) {
                              L.item_selected = position;
                              L.setSelection(position);
                              call_selected_event(X_L, L);
                          }
                      });
			        
                      return Result;
                  }
                  catch (Exception ex) { report(ex); }
                  return 0;
        \\    }
        \\});
	}

    /*
    
    FUNCTION Listbox_clear(INT H|andle_listbox), NATIVE : @
    	"AL4_form.do_Listbox_clear(X_H);" .	
    */	

	public static void do_Listbox_clear(int X_H) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      ListView L = (ListView)AL4_form.All_descr.get(X_H).Jvc;
                          ((ArrayAdapter)L.getAdapter()).clear();
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
	}    
    /*
    // Return listbox item string by its index
    //--------------------------------------------------------------------------
    
    FUN Get_listbox_item(
    INT L|istbox_control, INT Index|_item) ==> STR,
        NATIVE : "RESULT = AL4_form.do_Get_listbox_item(X_L, X_Index);" .
    */
    public static String do_Get_listbox_item(int X_L, int X_Index) {
        \\return get_property_string(new Callable<String>(){
        \\    @Override public String call() {
                  try {
                      ListView L = (ListView)AL4_form.All_descr.get(X_L).Jvc;
                      if (X_Index < 0 || X_Index >= L.getAdapter().getCount())
                         return "";
                      return L.getAdapter().getItem(X_Index).toString();
                  }
                  catch (Exception ex) { report(ex); }
                  return "";
        \\    }
        \\});
    }
    /*

    // Set listbox item string by its index
    //--------------------------------------------------------------------------
    
    FUN Set_listbox_item(
    INT L|istbox_control, INT Index|_item, STR Value|_set), NATIVE : @
        "	AL4_form.do_Set_listbox_item(X_L, X_Index, X_Value);" .
    */
    public static void do_Set_listbox_item(int X_L, int X_Index, String X_Value) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                     ListView L = (ListView)AL4_form.All_descr.get(X_L).Jvc;
                      if (X_Index < 0 || X_Index >= L.getAdapter().getCount())
                          return
                          \\null
                          ;
                      ((ArrayAdapter)L.getAdapter()).remove(
                         L.getAdapter().getItem(X_Index));
                      ((ArrayAdapter)L.getAdapter()).insert(X_Value, X_Index);
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
    }
    /*  

    // Get listbox items count
    //--------------------------------------------------------------------------
    
    FUN Get_listbox_count|_items(INT L|istbox_control) ==> INT,
        NATIVE : @
        "	RESULT = AL4_form.do_Get_listbox_count(X_L);" .
    */
    public static int do_Get_listbox_count(int X_L) {
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                      ListView L = (ListView)AL4_form.All_descr.get(X_L).Jvc;
                      return L.getAdapter().getCount();
                  }
                  catch (Exception ex) { report(ex); }
                  return 0;
        \\    }
        \\});
    }
    /*  
    // Add listbox item string 
    //--------------------------------------------------------------------------
    
    FUN Listbox_add_item(
    INT L|istbox_control, STR Value|_set) ==> INT,
        NATIVE :
	@	"RESULT = AL4_form.do_Listbox_add_item(X_L, X_Value);" .
	*/
	public static int do_Listbox_add_item(int X_L, String X_Value) {
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                      ListView L = (ListView)AL4_form.All_descr.get(X_L).Jvc;
                      ((ArrayAdapter)L.getAdapter()).add(X_Value);
                      return L.getAdapter().getCount()-1;
                  }
                  catch (Exception ex) { report(ex); }
                  return 0;
        \\    }
        \\});
	}
    /*

    // Insert item into listbox at given position 
    //--------------------------------------------------------------------------
    
    FUN Listbox_insert_item(
    INT L|istbox_control, INT Index|_before,
        STR Value|_set) ==> INT, NATIVE : @
    "	RESULT = AL4_form.do_Listbox_insert_item(X_L, X_Index, X_Value);" .
    */
    public static int do_Listbox_insert_item(int X_L, int X_Index, String X_Value) {
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                       ListView L = (ListView)AL4_form.All_descr.get(X_L).Jvc;
                       if (X_Index < 0 || X_Index > L.getAdapter().getCount())
                          return -1;
                       ((ArrayAdapter)L.getAdapter()).insert(X_Value, X_Index);
                       return X_Index;
                  }
                  catch (Exception ex) { report(ex); }
                  return 0;
        \\    }
        \\});
    }
    /*

    // Delete item in listbox by index 
    //--------------------------------------------------------------------------
    
    FUN Listbox_delete_item(
    INT L|istbox_control, INT Index|_delete), NATIVE : @
    "	AL4_form.do_Listbox_delete_item(X_L, X_Index);" .
    */
	public static void do_Listbox_delete_item(int X_L, int X_Index) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      ListView L = (ListView)AL4_form.All_descr.get(X_L).Jvc;
                      if (X_Index < 0 || X_Index >= L.getAdapter().getCount())
                          return
                          \\null
                          ;
                      ((ArrayAdapter)L.getAdapter()).remove(
                         L.getAdapter().getItem(X_Index));
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
	}    
    /*

    // Select/deselect item in listbox by index 
    //--------------------------------------------------------------------------
    
    FUN Listbox_select_item(
    {Listbox} L|istbox_control, INT Index|_of_item,
    BOOL Select|_or_deselect), NATIVE :
	INT h|andle_listbox = L.Handle
	BOOL mult|i_select = L.Multiselect
    	CASE Index < 0 && Select ? L.Listbox_select_none ==> ;
    NATIVE
	"	AL4_form.do_Listbox_select_item(X_Index, X_Select, X_h, X_mult);" .
   	*/
   	public static void do_Listbox_select_item(int X_Index,
   		boolean X_Select, int X_h, boolean X_mult) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                       AL4_ListView L = (AL4_ListView)AL4_form.All_descr.get(X_h).Jvc;
                       if (X_Index < 0 || X_Index >= L.getAdapter().getCount())
                          return
                          \\null
                          ;
                       if (X_Select) {
                          if (X_mult) L.setItemChecked(X_Index, true);
                          else {
                              L.setSelection(X_Index);
                              L.item_selected = X_Index;
                          }
                       }
                       else {
                          if (X_mult) L.setItemChecked(X_Index, false);
                          else L.item_selected = -1;
                       }
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
   	}
   	/*

    // Select all items in listbox
    //--------------------------------------------------------------------------
    
    FUN Listbox_select_all(
    {Listbox} L|istbox_control), NATIVE :
		INT h|andle_listbox = L.Handle
		BOOL mult|i_select = L.Multiselect
		CASE !mult ? ==> ;
		NATIVE @ "AL4_form.do_Listbox_select_all(X_h, X_mult);" .
	*/		
	public static void do_Listbox_select_all(int X_h, boolean X_mult) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                       ListView L = (ListView)AL4_form.All_descr.get(X_h).Jvc;
                       for (int i = 0; i < L.getAdapter().getCount(); i++)
                           L.setItemChecked(i, true);
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
	}

    /*
    // Deselect all items in listbox
    //--------------------------------------------------------------------------
    
    FUN Listbox_select_none(
    {Listbox} L|istbox_control), NATIVE :
		CASE !L.Multiselect ? ==> ;
		INT h|andle_listbox = L.Handle
		BOOL mult|i_select = L.Multiselect
		NATIVE @ " AL4_form.do_Listbox_select_none(X_h, X_mult);" .
    */
    public static void do_Listbox_select_none(int X_h, boolean X_mult) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                       AL4_ListView L = (AL4_ListView)AL4_form.All_descr.get(X_h).Jvc;
                       for (int i = 0; i < L.getAdapter().getCount(); i++)
                           L.setItemChecked(i, false);
                       L.item_selected = -1;
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
    }
    /*

    // Get count of selected items in listbox
    //--------------------------------------------------------------------------
    
    FUN Listbox_get_sel_count(
    {Listbox} L|istbox_control) ==> INT, NATIVE :
		//CASE !L.Multiselect ? 
		//     RESULT = 1 ==> ;
		INT h|andle_listbox = L.Handle
		BOOL mult|i_select = L.Multiselect
		NATIVE @
		" RESULT = AL4_form.do_Listbox_get_sel_count(X_h, X_mult);" .
    */
    public static int do_Listbox_get_sel_count(int X_h, boolean X_mult) {
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                       int RESULT = 0;
                       AL4_ListView L = (AL4_ListView)AL4_form.All_descr.get(X_h).Jvc;
                       if (!X_mult && L.item_selected < 0) return 0;
                       if (!X_mult) return 1;
                       SparseBooleanArray checked = L.getCheckedItemPositions();
                       for (int i = 0; i < checked.size(); i++)
                          if (checked.get(i)) RESULT ++ ;
                       return RESULT;
                  }
                  catch (Exception ex) { report(ex); }
                  return 0;
        \\    }
        \\});
    }
    /*

    // Delete all selected items in listbox
    //--------------------------------------------------------------------------
    
    FUN Listbox_delete_selected(
    {Listbox} L|istbox_control), NATIVE :
		//CASE !L.Multiselect ? ==> ;
		INT h|andle_listbox = L.Handle
		BOOL mult|i_select = L.Multiselect
		NATIVE @ " AL4_form.do_Listbox_delete_selected(X_h, X_mult);" .
    */
    public static void do_Listbox_delete_selected(int X_h, boolean X_mult) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                       AL4_ListView L = (AL4_ListView)AL4_form.All_descr.get(X_h).Jvc;
                       if (!X_mult) {
                          if (L.item_selected < 0)
                          	return
                          	\\null
                          	;
                          ((ArrayAdapter)L.getAdapter()).remove(
                              L.getAdapter().getItem(L.item_selected));
                       }
                       SparseBooleanArray checked = L.getCheckedItemPositions();
                       for (int i = L.getAdapter().getCount()-1; i >= 0; i--)
                            if (checked.get(i)) ((ArrayAdapter)L.getAdapter()).remove(
                              L.getAdapter().getItem(i));
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
    }
    /*


    // Get next selected item in listbox
    //--------------------------------------------------------------------------
    
    FUN Listbox_get_next_sel(
    {Listbox} L|istbox_control, INT From|_index) ==> INT, NATIVE :
		//CASE !L.Multiselect ? ==> ;
		INT h|andle_listbox = L.Handle
		BOOL mult|i_select = L.Multiselect
		NATIVE @ 
		" RESULT = AL4_form.do_Listbox_get_next_sel(X_From, X_h, X_mult);" .
    */
	public static int do_Listbox_get_next_sel(int X_From, int X_h, boolean X_mult) {
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                       AL4_ListView L = (AL4_ListView)AL4_form.All_descr.get(X_h).Jvc;
                       if (!X_mult) return L.item_selected;
                       SparseBooleanArray checked = L.getCheckedItemPositions();
                       for (int i = X_From+1; i < L.getAdapter().getCount(); i++)
                            if (checked.get(i)) return i;
                  }
                  catch (Exception ex) { report(ex); }
                  return -1;
        \\    }
        \\});
	}    
    
	//--------------------------------------------- C O M B O B O X (Spinner)

	/*
	// Create combobox control, return descriptor
	//-------------------------------------------
	FUN Create_combo({Control} C|ombo_control) ==> INT :
		//DEBUG: << "~~~~~~~~~~~~~~~~~ creating combo"#NL ;
		RESULT = do_create_combo(C.Form_.Handle, C) 
		//DEBUG: << "RESULT of Create_combo === " RESULT.S #NL ;
		.

	FUN do_create_combo(INT F|orm_handle,
		{Control} C|ombo_create) ==> INT, NATIVE :
		"     RESULT = AL4_form.Do_Create_combo(X_F, X_C);" .
	*/
	
	static void call_selected_event(Ref_obj X_C, View C) {
		try {
			C_Control CC = (C_Control)X_C.Obj;
    		//=======================================
    		//AL4_system.WriteLine("sel_change " + CC);
    		//=======================================
			C_Form F = (C_Form)CC.F_Form_.Obj;
	        if (operation_started(F, 6, CC.hard_link)) {
	        //------------------------------------------
                \\new Thread(
                \\    new Runnable() {
                \\        public void run() {
                              try {
                                  try {
                                  F.M_Notify_sel_change(CC.F_Form_);
                                  }
                                  finally {
                                  operation_ended(F, 6);
                                  }
                              }
                              catch (Exception ex) { report(ex); }
                \\        }
                \\    }
                \\).start();
	        //------------------------------------------
	        }
		} 
		catch(Exception ex) { report(ex); }

	}
	
	public static int Do_Create_combo(int H, Ref_obj X_C)
	{
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                      Spinner C = new Spinner(context_activity);
                      ArrayList<String> a = new ArrayList<String>();
                      ArrayAdapter<String> aa = new ArrayAdapter<String>(context_activity,
                          android.R.layout.simple_dropdown_item_1line, a);
                      C.setAdapter(aa);
				
                      int Result = add_control_single_line(H, C, X_C);
                  //AL4_system.WriteLine("just after adding control Result=" + Result);
			
                      //adjust_control_size_position(P, C);
                      Set_control_events(X_C, C, false);
			        
                      C.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                          @Override
                          public void onItemSelected(AdapterView<?> parent, View view,
                              int position, long id) {
                              call_selected_event(X_C, C);
                          }
			        	
                          @Override
                          public void onNothingSelected(AdapterView<?> parent) {
                              call_selected_event(X_C, C);
                          }
                      });
                  //AL4_system.WriteLine("returning the Result=" + Result);
                      return Result;
                  }
                  catch (Exception ex) { report(ex); }
                  return 0;
        \\    }
        \\});
	}

	/*
	// Return TRUE if combo can be edited (otherwise it can only be used to 
    // select items) ------------------------------------------------------
	FUN Get_combo_can_edit|_dummy(INT C|ombo_control_dummy) ==> BOOL,
ABANDONED('ComboBox must not be editable!') : .
	*/

	/*
	// Set combo style (TRUE - can be edited, FALSE - only select items)
	//------------------------------------------------------------------
	
	FUN Set_combo_can_edit|_dummy(INT C|ombo_control_dummy,
		BOOL E|nable_edit_dummy),
ABANDONED('ComboBox must not be editable!') : .
	*/

	/*
	// Fill combo items list with strings (separated by #CR or #NL)
	//-------------------------------------------------------------
	
	FUN Set_combo_items(INT C|ombo_control,
		STR V|alue_items), NATIVE :
	//DEBUG: << "called Set_combo_items " C.S " V=" V #NL ;
		STR a|rray_items[]
		INT from|_position = 0
	    FOR i IN [0 TO V.Len - 1] :
	        CASE from <= i && V.[i] == #CR ?
	             a[] << V.[from TO i-1]
	             from = i + 1 ;
	    ;
	    CASE from < V.Len ? a[] << V.[from TO *] ; 
	//DEBUG: << "splitted to " a[].Count.S " items: "#NL 
	//		FOR aa IN a[] : << aa #NL ;
	//		<< "---------------------" #NL ;
		FOR s IN a[] :
			CASE s.[0] == #LF ? s = s.[1 TO *] ;
			CASE s.[*] == #LF ? s = s.[0 TO *-1] ;
		    a[s.Index] = s ;
	//DEBUG: << "array ready count=" a[].Count.S #NL ;
		NATIVE @
		"    AL4_form.Do_Set_combo_items(X_C, X_a);" .
	*/
	public static void Do_Set_combo_items(int H, DynAStr X_a)
	{
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      Spinner C = (Spinner)AL4_form.All_descr.get(H).Jvc;
                  //AL4_system.WriteLine("Spinner filling........ " + C.toString());
                      ArrayAdapter<String> sa = (ArrayAdapter<String>)C.getAdapter();
                  //AL4_system.WriteLine("sa=" + sa.toString());
                      if (!(sa instanceof ArrayAdapter))
                      	return
                      	\\null
                      	;
                      ArrayAdapter<String> aa = (ArrayAdapter<String>) sa;
                      aa.clear();
                      for (int i = 0; i < X_a.Count(); i++) {
                          aa.add(X_a.Get_item(i));
                          //AL4_system.WriteLine("added item [" + X_a.Get_item(i) + "]");
                      }
                      C.setAdapter(aa);
                  //AL4_system.WriteLine("Spinner filled in");
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
	}

	/*
	// Get count items in combobox
	//---------------------------
	
	FUN Get_combo_count_items(
	INT C|ombo_control) ==> INT, NATIVE :
		"    RESULT = AL4_form.Do_Get_combo_count_items(X_C);" .
	*/
	public static int Do_Get_combo_count_items(int H)
	{
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                      Spinner C = (Spinner)AL4_form.All_descr.get(H).Jvc;
                      return C.getAdapter().getCount();
                  }
                  catch (Exception ex) { report(ex); }
                  return 0;
        \\    }
        \\});
	}

	/*
	// Get combobox item by index
	//---------------------------
	
	FUN Combo_get_item(
	INT C|ombo_control, INT Row|_combo) ==> STR, NATIVE :
		"    RESULT = AL4_form.Do_Get_combo_item(X_C, X_Row);" .
	*/
	public static String Do_Get_combo_item(int H, int Row) {
        \\return get_property_string(new Callable<String>(){
        \\    @Override public String call() {
                  try {
                      Spinner C = (Spinner)AL4_form.All_descr.get(H).Jvc;
                      return C.getAdapter().getItem(Row).toString();
                  }
                  catch (Exception ex) { report(ex); }
                  return "";
        \\    }
        \\});
	}

	/*
	// Set combobox item by index
	//---------------------------
	
	FUN Combo_set_item(
	INT C|ombo_control, INT Row|_combo, STR V|alue_set), NATIVE :
		"    AL4_form.Do_Set_combo_item(X_C, X_Row, X_V);" .
	*/
	public static void Do_Set_combo_item(int H, int Row, String V)	{
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      Spinner C = (Spinner)AL4_form.All_descr.get(H).Jvc;
                      ((ArrayAdapter<String>)C.getAdapter()).remove(
                          ((ArrayAdapter<String>)C.getAdapter()).getItem(Row));
                      ((ArrayAdapter<String>)C.getAdapter()).insert(V, Row);
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
	}

	/*
	// Search combobox item by String pattern
	//--------------------------------------
	
	FUN Find_combo_item(
	INT C|ombo_handle, STR F|inding_str) ==> INT
		:
        {Combo} combo|_control = get_combo_by_handle(C)
		FOR i IN [0 TO combo.Count-1] :
            CASE combo.Get_item(i, 0) == F ? RESULT = i ==> ;
        ; .
            
    FUN get_combo_by_handle(INT C|ombo_handle) ==> {Combo}, NATIVE :    
        "    RESULT = AL4_form.do_get_combo_by_handle(X_C);" .
	*/
    public static Ref_obj do_get_combo_by_handle(int C) {
        return AL4_form.All_descr.get(C).Ref;
    }

	/*
	// Add an item to the end of combobox
	//-------------------------------------
	
	FUN Add_combo_item(INT C|ombo_control, STR A|dding_str) ==> INT,
		NATIVE :
		"    RESULT = AL4_form.Do_Add_combo_item(X_C, X_A);" .
	*/
	public static int Do_Add_combo_item(int H, String X_A)
	{
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                      Spinner C = (Spinner)AL4_form.All_descr.get(H).Jvc;
                      ((ArrayAdapter<String>)C.getAdapter()).add(X_A);
                      return C.getAdapter().getCount() - 1;
                  }
                  catch (Exception ex) { report(ex); }
                  return 0;
        \\    }
        \\});
	}

	/*
	// Insert an item into combobox at a position
	//-------------------------------------
	
	FUN Insert_combo_item(INT C|ombo_control,
		INT I|ndex_where_insert, STR A|dding_str), NATIVE :
		"    AL4_form.Do_Insert_combo_item(X_C, X_I, X_A);" .
	*/
	public static void Do_Insert_combo_item(int H, int X_I, String X_A)
	{
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      Spinner C = (Spinner)AL4_form.All_descr.get(H).Jvc;
                      ((ArrayAdapter<String>)C.getAdapter()).insert(X_A, X_I);
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
	}

	/*
	// Get current index selected in combobox (-1 if nothing is selected)
	//-------------------------------------------------------------------
	
	FUN Get_combo_current_index(INT C|ombo_control) ==> INT,
		NATIVE :
		"    RESULT = AL4_form.Do_Get_combo_current_index(X_C);" .
	*/
	public static int Do_Get_combo_current_index(int H)
	{
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                      Spinner C = (Spinner)AL4_form.All_descr.get(H).Jvc;
                      return C.getSelectedItemPosition();
                  }
                  catch (Exception ex) { report(ex); }
                  return 0;
        \\    }
        \\});
	}

	/*
	// Set new current index (-1 is allowed to unselect all)
	//------------------------------------------------------
	FUN Set_combo_current_index(INT C|ombo_control, INT Index|_set),
		NATIVE :
		"    AL4_form.Do_Set_combo_current_index(X_C, X_Index);" .
	*/
	public static void Do_Set_combo_current_index(int H, int X_Index)
	{
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      Spinner C = (Spinner)AL4_form.All_descr.get(H).Jvc;
                      if (X_Index >= -1 && X_Index < C.getAdapter().getCount())
                          C.setSelection(X_Index);
                      else C.setSelection(-1);
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
	}

	/*
	// Get combo selection text
	//------------------------------
	
	FUN Get_combo_selection|_dummy(
	INT C|ombo_control_dummy) ==> STR,
ABANDONED('ComboBox can not be edited!') : .
	*/

	/*
	// Replace combo selection with another text
	//-----------------------------------------
	
	FUN Set_combo_selection|_dummy(INT C|ombo_control_dummy, 
        STR Text|_new_selection_dummy),
ABANDONED('ComboBox can not be edited!') : .
	*/

	/*
	// Set combo maximal length (of Edit sub-control part)
	//------------------------
	
	FUN Set_combo_max_len|_dummy(INT C|ombo_control_dummy, 
        INT V|alue_max_len_dummy),
ABANDONED('ComboBox can not be edited!') : .
	*/

	//-------------------------------------------- P R O G R E S S   B A R
    
	/*
	// Create progress bar control, return descriptor
	//----------------------------------------------
	FUN Create_progress_bar({Control} P|rogress_control) ==> INT :
		RESULT = do_create_progress(P.Form_.Handle, P) .

	FUN do_create_progress(INT F|orm_handle,
		{Control} P|rogress_bar_create) ==> INT, NATIVE :
		"     RESULT = AL4_form.Do_Create_progress_bar(X_F, X_P);" .
	*/
	public static int Do_Create_progress_bar(int H, Ref_obj X_P)
	{
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                  //AL4_system.WriteLine("creating ProgressBar");
                      ProgressBar PB = new ProgressBar(context_activity, null,
                          android.R.attr.progressBarStyleHorizontal);
                  //AL4_system.WriteLine("calling setMax");
                      PB.setMax(100);
                      int Result = add_control_single_line(H, PB, X_P);
                      //PB.setProgress(42);
                      Set_control_events(X_P, PB, true);
                  //AL4_system.WriteLine("return Result=" + Result);
                      return Result;
                  }
                  catch (Exception ex) { report(ex); }
                  return 0;
        \\    }
        \\});
	}

	/*
	// Get progress bar value
	//-----------------------
	FUN Get_progress_bar_value(INT P|rogress_control) ==> REAL,
		NATIVE :
		"    RESULT = AL4_form.Do_Get_progress_bar_progress(X_P);" .
	*/
	public static int Do_Get_progress_bar_progress(int H)
	{
		return get_property_int(new Callable<Integer>(){
			@Override public Integer call() {
				try {
					ProgressBar P = (ProgressBar)AL4_form.All_descr.get(H).Jvc;
					return P.getProgress();
				}
				catch (Exception ex) { report(ex); }
				return 0;
			}
		});
	}

	/*
	// Set progress bar value
	//-----------------------
	FUN Set_progress_bar_value(INT P|rogress_control, REAL V|alue_set),
		NATIVE :
		"   AL4_form.Do_Set_progress_bar_progress(X_P, X_V);" .
	*/
	public static void Do_Set_progress_bar_progress(int H, double Value)
	{
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      int v = (int)Value;
                      ProgressBar P = (ProgressBar)AL4_form.All_descr.get(H).Jvc;
                      if (P != null) {
                          if (Value >= 0 && Value <= P.getMax()) {
                              //AL4_system.WriteLine("setting progress bar[" + H +
                              //"] value " + Value + ", P=" + P.toString());
                              P.setProgress(v);
                              //AL4_system.WriteLine("value set for PB" + H);
                          }
                      }
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
	}

	/*
	// Get progress bar maximum
	//-----------------------
	FUN Get_progress_bar_maximum(INT P|rogress_control) ==> REAL,
		NATIVE :
		"    RESULT = AL4_form.Do_Get_progress_bar_maximum(X_P);" .
	*/
	public static int Do_Get_progress_bar_maximum(int H)
	{
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                      ProgressBar P = (ProgressBar)AL4_form.All_descr.get(H).Jvc;
                      return P.getMax();
                  }
                  catch (Exception ex) { report(ex); }
                  return 0;
        \\    }
        \\});
	}

	/*
	// Set progress bar maximum
	//-------------------------
	FUN Set_progress_bar_maximum(INT P|rogress_control, REAL V|alue_set),
		NATIVE :
		"   AL4_form.Do_Set_progress_bar_maximum(X_P, (int)X_V);" .
	*/
	public static void Do_Set_progress_bar_maximum(int H, int Value)
	{
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      ProgressBar P = (ProgressBar)AL4_form.All_descr.get(H).Jvc;
                      P.setMax(Value);
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
	}

	/*
	// Get progress bar minimum
	//-----------------------
	FUN Get_progress_bar_minimum(INT P|rogress_control) ==> INT,
		NATIVE :
		"    RESULT = AL4_form.Do_Get_progress_bar_minimum(X_P);" .
	*/
	public static int Do_Get_progress_bar_minimum(int H)
	{
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                      ProgressBar P = (ProgressBar)AL4_form.All_descr.get(H).Jvc;
                      return P.getMin();
                  }
                  catch (Exception ex) { report(ex); }
                  return 0;
        \\    }
        \\});
	}

	/*
	// Set progress bar minimum
	//-------------------------
	FUN Set_progress_bar_minimum(INT P|rogress_control, INT V|alue_set),
		NATIVE :
		"   AL4_form.Do_Set_progress_bar_minimum(X_P, X_V);" .
	*/
	public static void Do_Set_progress_bar_minimum(int H, int Value)
	{
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      ProgressBar P = (ProgressBar)AL4_form.All_descr.get(H).Jvc;
                      P.setMin(Value);
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
	}
    
 //------------------------------------------------------------ M E N U

	private static int Add_menu_items(MenuPanel MP, PopupMenu PM,
		SubMenu Parent_item, int idx, String[] L)
	{
		AL4_form form = MP.Form_;
		//AL4_system.WriteLine("build mennu __________________________");
	
		int i = idx - 1;
		while (i < L.length - 1)
		{
			i++;
			if (L[i].equals(")")) {
				idx = i; return idx;
			}
			String s = L[i];
			if (s.equals("-") || s.equals("")) continue;
			//AL4_system.WriteLine("handle item [" + s + "]");
			String a = s;
			int j = s.indexOf(':');
			if (j >= 0)
			{
				a = s.substring(0, j).trim();
				s = s.substring(j + 1).trim();
			}
            
            for (int k = s.length()-1; k >= 0; k --) {
                if (k > 0 && s.charAt(k-1) == '&' && s.charAt(k) == '&')
                    continue;
                if (s.charAt(k) == '&') {
                    s = (k > 0 ? s.substring(0, k) : "") 
                    + (k < s.length()-1 ? s.substring(k+1) : "");
                }
                else if (s.charAt(k) == '\t')
                    s = (k > 0 ? s.substring(0, k) : "") + "    " + 
                    (k < s.length()-1 ? s.substring(k+1) : "");
            }
            
            if (i < L.length - 1 && L[i + 1].equals("(")) {
                SubMenu Sub = Parent_item != null
                    ? Parent_item.addSubMenu(s)
                    : PM.getMenu().addSubMenu(s) ;
				i += 2;
				i = Add_menu_items(MP, PM, Sub, i, L);
            }
            else {
                String aa = a.toLowerCase();
                if (a.contains(",")) {
                    int pos_comma = a.indexOf(',');
                    a = a.substring(0, pos_comma);
                }
                //int item_id = MP.AllItemsList.size();
                MenuItem Item = (Parent_item != null
                	? Parent_item
                	: PM.getMenu())
                	//.add(-1, item_id, item_id, s);
                	.add(s);
                //if (aa.contains(",checked")) {
                if (aa.contains(",c")) {
                    //s = "* " + s;
                    Item.setCheckable(true);
                    Item.setChecked(true);
                }
                //if (aa.contains(",disabled"))
                if (aa.contains(",d"))
                    Item.setEnabled(false);
                else {
                	String alias = a;
                	Item.setOnMenuItemClickListener(
						new OnMenuItemClickListener(){
						@Override
						public boolean onMenuItemClick(MenuItem item) {
//?{Form}.menu_item
	                        C_Form CF = (C_Form)form.AL4Object;
	                        CF.F_menu_alias = alias;
	                        try {
		                        if (operation_started(CF, 20, CF.hard_link)) {
		                        //--------------------------------------------
                                    \\new Thread(
                                    \\    new Runnable() {
                                    \\        public void run() {
                                                  try {
                                                      try {
                                                          try {
                                                          CF.M_menu_item();
                                                          }
                                                          finally {
                                                          operation_ended(CF, 20);
                                                          }
                                                      }
                                                      finally {
                                                          CF.F_menu_alias = "";
                                                      }
                                                  }
                                                  catch (Exception ex) { report(ex); }
                                    \\        }
                                    \\    }
                                    \\).start();
		                        //--------------------------------------------
		                        }
							}
							catch (Exception ex) { }
//.
							return true;
						}
					});
                }
                //MP.AliasesList.add(a);
                //MP.AllItemsList.add(Item);
            }
		}
        return i;
	}

	public static MenuPanel Do_Create_menu(int H, String X_V)
	{
        AL4_form.AL4Column P = AL4_form.Get_parent_for_new_control(H);
        MenuPanel MP = new MenuPanel();
        MP.Form_ = P.Form_;
        try {
        	if (P.Layout >= 4)
        		P = P.Form_.Columns.get(0);
        	View anchor_view = P.TV;
            MP.MenuObject = new PopupMenu(context_activity, anchor_view);
        //---------------------------------------------------
        //AL4_system.WriteLine("column=" + P + "\nalias=" +
        //P.Alias + " anchor view = " + anchor_view);
		//---------------------------------------------------
            //------------------------------------- fill menu items tree 
            String[] L = X_V.split("" + (char)13);
            for (int i=0; i < L.length; i++) {
                L[i] = L[i].trim();
            }
            int j = 0;
            j = Add_menu_items(MP, MP.MenuObject, null, j, L);
        }
        catch (Exception E) { report(E); }
        return MP;
	}
    

	public static void Do_Destroy_menu(MenuPanel MP)
	{
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      MP.Form_ = null;
                      MP.MenuObject = null;
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
	}

	/*
	// Show menu, return selected item's alias
	//------------------------------------------------------------------------
	
    FUN Popup_menu(
    {Form} F|orm_showing_menu, STR M|enu_definition)
    	:
        do_popup_menu(F.Handle, M) .
    FUN do_popup_menu(
    	INT F|orm_handle, STR M|enu_definition), NATIVE :
        "    AL4_form.Do_Popup_menu(X_F, X_M);" .
	*/
    
	public static void Do_Popup_menu(int H, String Mdef)
	{
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      MenuPanel MP = Do_Create_menu(H, Mdef);
                      AL4_form form = MP.Form_;
			
                      if (form.Form.getVisibility() != View.VISIBLE) {
                          activate_form(form);
                      }
                      MP.MenuObject.show();
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
	}
    
    public static class MenuPanel 
    {
        public AL4_form Form_;
        public PopupMenu MenuObject;
    }
    
	//--------------------------------------------------------------- T I M E R

	/*
	
	FUN Time_BeginPrecision(
	INT Prec|ision_milliseconds) : .
		
	FUN Time_EndPrecision(
	INT Prec|ision_milliseconds) : .
	
	// Create timer, return descriptor
	//--------------------------------------------------------------------------
	FUN Create_timer({Control} T|imer_object,
		INT Interval, BOOL Active|_state) ==> INT
        :
        RESULT = do_create_timer(T.Form_.Handle, T)
		Set_timer_interval(RESULT, Interval)
		Set_timer_active(RESULT, Active) .

	FUN do_create_timer(INT F|orm_handle,
		{Control} T|imer_create) ==> INT, NATIVE :
		"     RESULT = AL4_form.Do_Create_timer(X_F, X_T);" .
	*/
    
	public static int Do_Create_timer(int H, Ref_obj X_T)
	{
        \\return get_property_int(new Callable<Integer>(){
        \\    @Override public Integer call() {
                  try {
                      AL4_form.AL4Column P = AL4_form.Get_parent_for_new_control(H);
                      AL4_form f = (AL4_form)AL4_form.All_descr.get(H).Jvc;
                      TimerPanel TP = new TimerPanel(f, X_T, true);
                      int Result = AL4_form.Alloc_descriptor(TP, X_T);
                      return Result;
                  }
                  catch (Exception ex) { report(ex); }
                  return 0;
        \\    }
        \\});
	}

	/*
	// Set timer Interval
	//-------------------
	FUN Set_timer_interval(INT T|imer_control, INT V|alue_interval),
		NATIVE :
		"    AL4_form.Do_Set_timer_interval(X_T, X_V);" .
	*/
	public static void Do_Set_timer_interval(int H, int X_V)
	{
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      TimerPanel TP = (TimerPanel)AL4_form.All_descr.get(H).Jvc;
                      TP.Interval = X_V;
                      Do_Set_timer_active(H, TP.Active);
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
	}

	/*
	// Set timer Active state
	//-----------------------
	FUN Set_timer_active(INT T|imer_control, BOOL A|ctive_state),
		NATIVE :
		"    AL4_form.Do_Set_timer_active(X_T, X_A);" .
	*/
	public static void Do_Set_timer_active(int H, boolean X_A) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      TimerPanel TP = (TimerPanel)AL4_form.All_descr.get(H).Jvc;
                      Do_TimerPanel_Set_active(TP, X_A);
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
	}
    
    public static void Do_TimerPanel_Set_active(TimerPanel TP, boolean X_A) {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      if (TP.TimerObject != null) {
                          TP.form.All_timers.remove(TP.TimerObject);
                          TP.TimerObject.cancel();
                          TP.TimerObject = null;
                      }
                      TP.Active = X_A;
                      if (X_A) {
                          TP.TimerObject = new Timer();
                          TP.form.All_timers.add(TP.TimerObject);
                          TP.create_Task();
                          TP.TimerObject.schedule(TP.Task, TP.Interval, TP.Interval);
                      }
              //if (!X_A) AL4_system.WriteLine("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" +
              //" timer deactivated"); else AL4_system.WriteLine("$$$$$$$$$$$$$$$ activated");
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
    }
    
    public static ReentrantLock locker = new ReentrantLock();

    public static class TimerPanel 
    //extends View
    {
        public AL4_form form;
        public Ref_obj This_control;
        public Timer TimerObject;
        public TimerTask Task;
        public boolean Active;
        public int Interval;
        
        public Handler mHandler;
        
        public void create_Task() {
        	mHandler = new Handler() {
        		public void handleMessage(Message msg) {
        			//AL4_form.locker.lock();
        			try {
	                    try {
	                    	if (form.Disable_timers) return;
		                    C_Form F = (C_Form)AL4_form.All_descr.get(form.Handle).Ref.Obj;
		                    AL4_form aF = (AL4_form)AL4_form.All_descr.get(F.F_Handle).Jvc;
		                    if (aF == null || !aF.Form.isEnabled()
		                    	|| F == null || This_control == null)
		                    	return;
							if (last_FuttureTask_down != null) {
								last_FuttureTask_down.get();
								last_FuttureTask_down = null;
							}
		                    if (operation_started(F, 18, This_control)) {
		                    //-------------------------------------------
                                \\run_on_background_wait(new Callable<Integer>(){
                                \\    @Override public Integer call() {
                                          try {
                                              try {
                                                  F.M_timer();
                                              }
                                              finally {
                                                  operation_ended(F, 18);
                                              }
                                          }
                                          catch (Exception ex) { report(ex); }
                                \\        return 0;
                                \\    }
                                \\});
		                    //-------------------------------------------
		                    }
	                    }
	                    catch(Exception ex) { report(ex); }
        			}
        			finally {
        				//AL4_form.locker.unlock();
        			}
        		}
        	};
            Task = new TimerTask() {
                @Override
                public void run() {
                    try {
                    	mHandler.obtainMessage(1).sendToTarget();
                    }
                    catch(Exception ex) { report(ex); }
                }
            };
        }
        
        public TimerPanel(AL4_form f, Ref_obj this_contr, boolean need_task) {
            form = f;
            This_control = this_contr;
            Interval = 1000;
            if (need_task) create_Task();
            f.Trays_timers.add(this);
        }
        
    }
    
    public void Deactivate_trays_timers() {
        \\run_on_ui_thread(false, new Callable<Void>(){
        \\    @Override public Void call() {
                  try {
                      for (int i = 0; i < Trays_timers.size(); i++)
                          if (Trays_timers.get(i) instanceof TimerPanel) {
                              //AL4_system.WriteLine("STOP ONE TIMER");
                              Do_TimerPanel_Set_active((TimerPanel)(Trays_timers.get(i)),
                                          false);
                          }
                  }
                  catch (Exception ex2) { report(ex2); }
        \\        return null;
        \\    }
        \\});
    }
    
    //------------------------------------------------------------ T R A Y
    /*
    // Create tray icon component.
    //----------------------------------------------------------------------
    FUN Create_tray_icon({Control} T|ray_icon_object, 
        {Icon} Icon|_handle) ==> INT, UNCOOKED : .
    */
    
    public ArrayList<TimerPanel> Trays_timers = new ArrayList<TimerPanel>();


    /*
    // Set tray icon text.
    //----------------------------------------------------------------------------
    FUN Set_tray_icon_text( INT Handle|_tray_icon_object, 
        STR S|how_text ), UNCOOKED : .
    */
    
    /*
    // Destroy try icon object.
    //----------------------------------------------------------------------------
    FUN Destroy_tray_icon( INT Handle|_tray_icon_object), UNCOOKED : .
        
    // Destroy icon.
    //----------------------------------------------------------------------------
    FUN Destroy_icon( INT Handle|_icon), UNCOOKED : .
        
    // Load icon from file.
    //----------------------------------------------------------------------------
    FUN Load_icon_from_file( STR Path|_to_file_containing_icon ) ==> INT,
        UNCOOKED : .
    */
    
    /*
    // Replace tray icon by another icon object
    //----------------------------------------------------------------------
    FUN Replace_tray_icon( INT Handle|_tray_icon_object,
        {Icon} Value|_icon_to_set ), UNCOOKED : .
    //@   "   //AL4_form.Do_replace_tray_icon(X_Handle, X_Value);" .
    */       
            

	/*
	// Process all messages
    //------------------------------------
    
    FUN Process_all_form_messages|_DUMMY(
    INT H|andle_form_dummy) : .
       
    */
    public static void temp_file_write() {
    	try {
    		String dir = context_activity.getExternalFilesDir(null).toString() 
    					 + '/';
	    	File temp = new File(dir + "temp.$$$");
	    	if (temp.isFile()) temp.createNewFile();
	    	RandomAccessFile raf = new RandomAccessFile(temp, "rw");
	    	raf.seek(0);
	    	byte[] dummy = new byte[1];
	    	dummy[0] = (byte)1;
	    	raf.write(dummy, 0, 1);
	    	raf.close();
    	}
    	catch (Exception ex) { report(ex); }
    }
    
    
	//------------------------------------------------------------
	public boolean Hidden;
    C_Form AL4Object;
	public ArrayList<AL4Column> Columns = new ArrayList<AL4Column>();
	
	public boolean is_single_client_column() {
		int count_client = 0;
		for (int i = 0; i < Columns.size(); i++) {
			AL4Column col = Columns.get(i);
			if (col.Layout == 1 || col.Layout == 2) return false;
			if (col.Layout != 0) continue;
			if (col.getVisibility() == View.GONE) continue;
			count_client += 1;
		}
		return count_client <= 1;
	}
	
	public boolean no_top_bottom_columns() {
		for (int i = 0; i < Columns.size(); i++) {
			AL4Column col = Columns.get(i);
			if (col.Layout == 3 || col.Layout == 4) {
			 	return false;
			}
		}
		return true;
	}

	// Form construction. By default, appearing position set to Default
	public AL4_form(Ref_obj form_AL4) throws Exception
	{
		context_activity = MainActivity.main_activity;
		Handle = AL4_form.Alloc_descriptor(this, form_AL4);
		//StartPosition = FormStartPosition.WindowsDefaultLocation;
		C_Form cF = (C_Form)form_AL4.Obj;
        AL4Object = cF;
	}

	// Form destruction: releasing descriptor for a form
    public void dispose()
	{
        //Form.setTitle("Disposing!!!");
        //AL4_system.WriteLine("~~~~~~~~~~ Disposing form: " + this);
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        a_content.setVisibility(View.GONE);
        Forms_shown.remove(this);
        Deactivate_trays_timers();
		ReleaseDescriptor(Handle);
        Handle = 0;
        //Form.dispose();
	}

	//------------------------------- AL4_form events:

	// any control is clicked
	public static boolean click_disabled;
	public static int next_click_disabled;

    /*
	// Get point on form used to pop up menu by default
	//-------------------------------------------------
	
	FUN Get_form_popup_point(
	INT F|orm_handle) ==> {point}
		:= Pt(F.get_form_popup_point(TRUE), F.get_form_popup_point(FALSE)) .
	FUN get_form_popup_point(
        INT F|orm_handle, BOOL X|_coordinate) ==> REAL, NATIVE :
		CASE F == 0 ? ==> ;
		NATIVE @ 
        "    AL4_form form = (AL4_form)AL4_form.All_descr.get(X_F).Jvc;"
        "    if (X_X) RESULT = form.Popup_point.x;"
        "    else RESULT = form.Popup_point.y;" .

	FUNCTION Set_form_popup_point(
        INT F|orm_handle, 
        REAL Px|_coordinate_points, REAL Py|_coordinate_points), 
        NATIVE : @
            "    AL4Form form = (AL4Form)AL4Form.All_descriptors[(int)X_F];"
            "	 if (form == null) return;"
            "	 form.Popup_point.X = (float)X_Px;"
            "    form.Popup_point.Y = (float)X_Py;" .

    // Get mouse point on form for current mouse event
	//-------------------------------------------------
	
	FUN Form_get_mouse_point(
	INT F|orm_handle) ==> {point}
		:= Pt(F.get_mouse_point(TRUE), F.get_mouse_point(FALSE)) .
	FUN get_mouse_point(
	INT F|orm_handle, BOOL X|_coordinate) ==> REAL, NATIVE :
			CASE F == 0 ? ==> ;
			NATIVE @
        "    AL4_form form = (AL4_form)AL4_form.All_descr.get(X_F).Jvc;"
        "    if (X_X) RESULT = AL4_form.Pixels(form.Mouse_point.x);" 
        "    else RESULT = AL4_form.Pixels(form.Mouse_point.y);" .
        
    // Get mouse button clicked
	//-------------------------------------------------
	FUN Form_mouse_button(INT F|orm_handle) ==> {Form}.{button}, NATIVE :
       @"    AL4_form form = (AL4_form)AL4_form.All_descr.get(X_F).Jvc;"
        "    RESULT = (byte)form.Mouse_button;" .
        
    // Get mouse wheel distance
	//-------------------------------------------------
	FUN Form_vertical_wheel(INT F|orm_handle) ==> REAL, NATIVE :
       @"    AL4_form form = (AL4_form)AL4_form.All_descr.get(X_F).Jvc;"
        "    RESULT = form.Mouse_wheel_vertical;" .
        
    // Get mouse wheel horizontal distance
	//-------------------------------------------------
	FUN Form_horizontal_wheel(INT F|orm_handle) ==> REAL, NATIVE :
       @"    AL4_form form = (AL4_form)AL4_form.All_descr.get(X_F).Jvc;"
        "    RESULT = form.Mouse_wheel_horizontal;" .
	*/
    public PointF Popup_point = new PointF(0, 0);
    public PointF Mouse_point = new PointF(0, 0);
    public int Mouse_button;
    public double Mouse_wheel_vertical;
    public double Mouse_wheel_horizontal;
    
    
    /*
    
	FUN Get_mouse_cursor_position ==> {Geometry}.{point}
		:
		REAL mp|oint_xy[] << 0 << 0
		get_mouse_cursor(mp[])
		RESULT = Pt(mp[0], mp[1]) .
	FUN get_mouse_cursor(REAL MP|osition[]), UNCOOKED : .
	
	FUN Set_new_mouse_cursor_position(
	REAL X|_coordinate_points, REAL Y|_coordinate_points) : // just ignored
	.

	FUN Is_mouse_button_pressed(
	{button} Button|_checked) ==> BOOL, UNCOOKED : .
	
   	FUN Is_keyboard_key_pressed(
   	INT Key|_interesting) ==> BOOL, UNCOOKED : .

	
    
    FUNCTION Control_selection_change(
    {Control} C|ontrol_changed)
    	:
        PUSH C.Form_.sender_ = C :
        	 {Form}.Notify_sel_change(C.Form_) ; .
    */
    
    public Timer waiter;
    public final Boolean use_waiter = true;
    
    public static class AL4Column extends LinearLayout 
    {
        public AL4_form Form_;
        public int Handle;
        public String Alias;
        public boolean Horizontal;
        public int Layout;
        public LinearLayout table_content;
        public TableRow prev_label_row;
        public boolean No_labels;
        public boolean Nesting;
        
        public double Width_points;
        public double Height_points;
        public TextView TV;
        
        public ArrayList<Ref_obj> Child_controls = new ArrayList<Ref_obj>();
	
        public AL4Column(AL4_form F)
        {
        	super(context_activity);
            Form_ = F;
            Handle = AL4_form.Alloc_descriptor(this, null);
        }
        
        public static String spec(int spec) {
        	String result = "";
        	switch(MeasureSpec.getMode(spec)) {
        	case MeasureSpec.EXACTLY: result = "EXACTLY"; break;
        	case MeasureSpec.AT_MOST: result = "AT_MOST"; break;
        	default: result = "DEFAULT"; break; 
        	}
        	result += ":" + MeasureSpec.getSize(spec);
        	return result;
        }
        
        static boolean measuring = false;
        int last_display_w;
        int last_hview_h;
        
        @Override
        public void onMeasure(int wSpec, int hSpec) {
        try {
            if (measuring) {
                super.onMeasure(wSpec, hSpec);
                return;
            }
            measuring = true;
            try {
                DisplayMetrics dM = new DisplayMetrics();
                context_activity.getWindowManager().getDefaultDisplay()
                .getMetrics(dM);
                int display_w = dM.widthPixels;
                int display_h = dM.heightPixels;
                if (last_display_w != display_w ||
                	last_hview_h != context_activity.HView.getHeight()) {
            //------------------------------------------------------------------
            if (Nesting) {
            C_Log_html.M_Log_colored(0,"^^^^^^^^^^^^ changing display_w " +
            last_display_w + " -> " + display_w + ", display_h=" + display_h +
            "\nHView.h=" + context_activity.HView.getHeight() +
            '\n');
            }
            //------------------------------------------------------------------
                    last_display_w = display_w;
                    last_hview_h = context_activity.HView.getHeight();
                }
                if (Form_ != null && Form_.Form.getHeight() < display_h) {
                    int[] XY = new int[2];
                    Form_.Form.getLocationInWindow(XY);
                    int form_h = Form_.Form.getHeight();
                    if (XY[1] == 0) display_h = form_h;
                    else display_h -= XY[1];
            //------------------------------------------------------------------
            if (Nesting) {
            AL4_system.WriteLine("XY=" + XY[0] + "," + XY[1] + ", display_h="
            + display_h + ", form_h=" + form_h);
            }
            //------------------------------------------------------------------
                }
        	
                boolean widening = false;
                boolean heightening = false;
                char mode_w = ' ';
                switch(MeasureSpec.getMode(wSpec)) {
                case MeasureSpec.EXACTLY: mode_w = 'E'; break;
                case MeasureSpec.AT_MOST: mode_w = 'A'; break;
                }
                char mode_h = ' ';
                switch(MeasureSpec.getMode(hSpec)) {
                case MeasureSpec.EXACTLY: mode_h = 'E'; break;
                case MeasureSpec.AT_MOST: mode_h = 'A'; break;
                }
                
                int wIn = MeasureSpec.getSize(wSpec);
                int hIn = MeasureSpec.getSize(hSpec);
                int wSet = Points(Width_points);
                int hSet = Points(Height_points);
            //-----------------------------------------------------------
            if (Nesting) {
            AL4_system.WriteLine("display size: " + display_w + " X " +
            display_h + " wSet=" + wSet + " hSet=" + hSet);
            }
            //-----------------------------------------------------------
                int w = wSet;
                int h = hSet;
                int h_max = display_h;
                
                if (wSet <= 0 && Form_ != null) {
                    switch(Layout) {
                    case 3:
                    case 4: w = Form_.Form.getWidth();
                            if (w < display_w) w = display_w;
                            widening = true;
                            break;
                    case 0: if (Form_.is_single_client_column()) {
                                w = display_w;
                                widening = true;
                            }
                            break;
                    }
                }
                if (hSet <= 0 && Form_ != null) {
                    switch(Layout) {
                    case 1:
                    case 2: if (Form_.no_top_bottom_columns()) {
                                h = context_activity.HView.getHeight();
                                if (h == 0) {
	                                h = Form_.Form.getHeight() - 2;
	                                if (h > display_h) h = display_h;
                                }
                                //-------------------------------
                                //if (is_soft_keyboard_visible &&
                                //    keyboard_height > 0) {
                                //    h -= keyboard_height;
                                //}
                                //-------------------------------
                                heightening = true;
                            }
                            break;
                    case 0: if (Form_.no_top_bottom_columns()) {
                                h = context_activity.HView.getHeight();
                                if (h == 0) {
                                	h = display_h;
                                }
                                heightening = true;
                            } else {
                                h = display_h * 3 / 4;
                                heightening = true;
                            }
                            break;
                            
                    }
                    if (Layout <= 2 && getChildCount() > 1
                    	|| Layout >= 3 && hSet > 0)
                    {
                    	for (int i = 0; i < getChildCount(); i++) {
                    		View child_i = getChildAt(i);
                    		if (child_i.getVisibility() == View.GONE) continue;
                    		if (child_i.getTop() + child_i.getHeight() > h) {
                    			h = child_i.getTop() + child_i.getHeight();
                    	//-------------------------------------------------
                    	if (Nesting) {
                        AL4_system.WriteLine("vvvvvvvvvvvvv set h=" + h +
                        " as the bottom of the last control");
                    	}
                    	//-------------------------------------------------
                    			heightening = true;
                    		}
                    	}
                    }
                }
                
                if (w <= 0) w = wIn;
                if (w <= 0) w = wSet;
                
                if (h <= 0) h = hIn;
                if (h <= 0) h = hSet;
                if (w <= 0)
                    switch(Layout) {
                    case 0: w = Points(200); break;
                    case 1:
                    case 2: w = Points(100); break;
                    case 3:
                    case 4: w = Points(400); break;
                    }
                
                switch(mode_w) {
                case 'E': w = wIn; break;
                case 'A': w = Math.min(wIn, w); break;
                default: w = w; break;
                }
                
                switch(mode_h) {
                case 'E': h = hIn; break;
                case 'A': h = Math.min(hIn, h); break;
                default: h = h; break;
                }
                
                if (Layout >= 3 && hSet > 0)
                	h = hSet;
                	
                int passW = //(mode_w == 'E' || mode_w != 'A' && !widening)
                            mode_w == 'E' || !widening
                            ? wSpec
                            : MeasureSpec.makeMeasureSpec(w,
                              widening && w > 0
                              ? MeasureSpec.EXACTLY
                              : w > 0
                                ? MeasureSpec.AT_MOST
                                : MeasureSpec.getMode(wSpec));
                int passH = (mode_h == 'E' ||
                             mode_h != 'A' && !heightening &&
                             !Form_.no_top_bottom_columns())
                            ? hSpec
                            : MeasureSpec.makeMeasureSpec(h,
                              heightening && h > 0
                              ? MeasureSpec.EXACTLY
                              : h > 0
                                ? MeasureSpec.AT_MOST
                                : MeasureSpec.getMode(hSpec));
                Width_pixels = MeasureSpec.getSize(passW);
                Height_pixels = MeasureSpec.getSize(passH);
                if (Height_pixels > h_max) Height_pixels = h_max;
        //-------------------------------------------------------
        //-------------------------------------------------------
                super.onMeasure(passW, passH);
            }
            finally {
                measuring = false;
            }
        }
        catch (Exception ex) { report(ex); }
        }
        
        int Width_pixels;
        int Height_pixels;
        
        public void dispose()
        {
        	Form_.Columns.remove(this);
            AL4_form.ReleaseDescriptor(Handle);
        }
        
    }
    
    public static class Animation_timer extends Timer {
        AL4_form form;
        Ref_obj Ref_control;
        public int Counter;
        public int Last_counter;
        TimerTask TT;
        public int Control_handle;
        public Handler mHandler;
        
        public Animation_timer(int X_H, int X_Count, int X_Interval)
        {
        	Control_handle = X_H;
            View C = (View)AL4_form.All_descr.get(X_H).Jvc;
            Ref_control = (Ref_obj)AL4_form.All_descr.get(X_H).Ref;
            Ref_obj fF = ((C_Control)(Ref_control.Obj)).F_Form_;
            C_Form cF = (C_Form)fF.Obj;
            form = (AL4_form)AL4_form.All_descr.get(cF.F_Handle).Jvc;
            
            // remove all animation timers earlier created for the control
            for (int i = form.Control_timers.size()-1; i >= 0; i--) {
            	Animation_timer a_t = form.Control_timers.get(i); 
            	if (a_t.Ref_control.Obj == Ref_control.Obj) {
            		a_t.cancel();
            		form.All_timers.remove(a_t);
            		form.Control_timers.remove(a_t);
            	}
            }
            
            form.Control_timers.add(this);
            
            Last_counter = X_Count;
            
            mHandler = new Handler() {
        		public void handleMessage(Message msg) {
                    try {
                        if (++Counter >= Last_counter)
                            Stop_timer();
                        C_Control CC = (C_Control)Ref_control.Obj;
                        C_Form F = (C_Form)CC.F_Form_.Obj;
                        
		                if (operation_started(F, 2, CC.hard_link)) {
		                //------------------------------------------
                            \\new Thread(
                            \\    new Runnable() {
                            \\        public void run() {
                                          try {
                                              try {
                                              CC.M_animation();
                                              }
                                              finally {
                                              operation_ended(F, 2);
                                              }
                                          }
                                          catch (Exception ex) { report(ex); }
                            \\        }
                            \\    }
                            \\).start();
		                //------------------------------------------
		                }
                    }
                    catch(Exception ex) { report(ex); }
        		}
        	};

            TT = new TimerTask() {
                @Override
                public void run() {
                    try {
                    	mHandler.obtainMessage(1).sendToTarget();
                    }
                    catch(Exception ex) { report(ex); }
                }
            };
            form.All_timers.add(this);
            schedule(TT, X_Interval, X_Interval);
        }
        
        public void Stop_timer()
        {
            try {
                cancel();
                TT = null;
                form.Control_timers.remove(this);
                //Ref_control.Ref_dec_hard();
            }
            catch (Exception ex) { report(ex); }
        }
    }
    
    public ArrayList<Timer> All_timers = new ArrayList<Timer>();
    
    public void Cancel_all_timers() {
        for (int i = All_timers.size() - 1; i >= 0; i--) {
            All_timers.get(i).cancel();
            if (All_timers.get(i) == waiter)
                waiter = null;
        }
        All_timers.clear();
    }
    
	public static class Screen_handler extends AL4_handler
    {
        C_Screen Scr;
        public static double Last_time;
        
        /*
        
        FUN get_Last_time_activity ==> REAL,
        UNCOOKED, PUBLIC : .
        
        FUN do_Last_time_set, UNCOOKED, PUBLIC : .
        
        */
        
        
        public Screen_handler(Ref_obj X_Screen)
        {
        }
        
		@Override
        public void Handler() 
        {
        }
        
        
    }	
    
}

/*
END
*/
