/*******************************************************************************
 Module Interactivity
 Editor part
 Version: 1.0
 Authors: Jean-Pierre Dandrieux, Julien Zorko, Gilles Marchal, Julien Ducoin
 Last update: 12/06/2001
 1 to 1 Audio/Video/Text communication system
*******************************************************************************/

var INFO_SUP_HEIGHT = 425;;
var INFO_FIELDS_NUMBER = 5;;
var UNDEFINED_FIELD = "#undefined";;

typeof Ed = Editor;;                                                /* Editor */
typeof EditorWin = ObjWin;;                                  /* editor window */
typeof UserTypeLabel = ObjText;;              /* Label for the following list */
typeof UserTypeList = ObjList;;      /* List of kind of users and their right */
typeof AddButton = ObjButton;;               /* Button adding a kind of users */
typeof DelButton = ObjButton;;             /* Button deleting a kind of users */
typeof ModifyButton = ObjButton;;           /* Button to edit the user rights */
typeof FieldNameLabel = ObjText;;                     /* info field list label*/
typeof FieldNameList = [[ObjText ObjText]r1];;  /* info field names interface */ 

typeof InfoSupLabel = ObjText;;
typeof UserTypeField = ObjText;;       /* User Type field in the popup window */
typeof UserRightsField = ObjText;;   /* User Rights field in the popup window */
typeof AdminLevelItemLabel = ObjText;;    /* Admin user level item name label */
typeof AdminLevelItem = ObjText;;               /* Admin user level item name */
typeof SQLsourceLabel = ObjText;;                /* Data base from ODBC label */
typeof SQLsource = ObjText;;                           /* Data base from ODBC */
typeof SQLconnection = ObjButton;;              /* Button to connect to the DB */
typeof SQLtableLabel = ObjText;;                         /* SQL request Label */
typeof SQLtable = ObjBox;;                                     /* SQL request */

typeof LoginLabel = ObjText;;
typeof Login = ObjBox;;

typeof EmailLabel = ObjText;;
typeof Email = ObjBox;;

typeof SendEmailLabel = ObjText;;
typeof SendEmail = ObjBox;;

typeof EmailExpeditorLabel = ObjText;;
typeof EmailExpeditor = ObjText;;

typeof DBotherFieldsLabel = ObjText;;
typeof DBotherFieldsAliasLabel = ObjText;;
typeof DBotherFieldsAlias = ObjText;;
typeof DBotherFieldsList = ObjListTab;;

typeof OtherFields = [[S r1] r1];;
typeof Selection = I;;
typeof OldDB = S;;
typeof OldTable = S;;
typeof DB = SqlDB;;

/*******************************************************************************
 Communication parameters edition
*******************************************************************************/
typeof FramerateCombo = ObjBox;;
typeof WidthCombo = ObjBox;;
typeof QualityCombo = ObjBox;;

typeof FreqMulCombo =  ObjBox;;
typeof SampleCombo =  ObjBox;;
typeof StereoCombo =  ObjBox;;

typeof SYCproxyAudio = ObjCheck;;
typeof SYCproxyVideo = ObjCheck;;
typeof SYCproxyText = ObjCheck;;

typeof nbEventRelay = ObjText;;

/* SYCbaseFrequency is the frequency whose multiple we will use to set the
   sampling */
var SYCbaseFrequency=5512;;

struct TaudioParam=
[
  Aid            : S, /* user id ot the param owner */
  FreqMultiplyer : S, /* Value 1 : 5,5khz ,2 : 11khz ,4 : 22khz or 8 : 44 khz */
  nBuffers       : S, /* nBuffers is the number of buffers captured during the SYCrecording */
  Sample         : S, /* value 1 : 8 bits or 2 : 16 bits */
  Stereo         : S  /* value 1:mono or 2:stereo */
] mkTaudioParam;;

struct TvideoParam=
[
  Vid        : S, /* user id ot the param owner */
  Framerate  : S, /* Delay between 2 images in microsec */
  Width      : S, /* Width in pixel, the height is autocalculated in a 4/3 format */
  nbcolor    : S, /* Not implemented yet in the SYCwebcam driver */
  Quality    : S  /* Compression factor */
] mkTvideoParam;;


fun NilToEmptyStr (str)=
  if str == nil then
    "" 
  else 
    str
;;

fun DBchanged () =
  strcmp OldDB _GETtext SQLsource
;;  

fun TableChanged () =
  let _GETcombo SQLtable -> [_ table] in
  strcmp OldTable table
;;


fun GetODBCInfos(odbcAlias,info)=
  hd switchstr strextr _loadressini strcatn "odbc."::odbcAlias::"."::info::nil
;;

fun GetUserRightsList (n) =
  if (n==nil) || (n>=(_GETlistCount UserTypeList)) then
    nil
  else
    let _GETlist _SELlist UserTypeList n -> [_ content] in
      content::(GetUserRightsList n+1)
;;

fun FillCombo (combo, list, ind) =
  if list == nil then 
    0
  else 
    let list -> [first next] in
    (
      _ADDcombo combo ind hd first;
      FillCombo combo next ind+1
    )
;;


/*******************************************************************************
  Change the alias of a field
*******************************************************************************/
fun ModifyFieldAlias (list, name, alias) =
  if list == nil then 
    nil
  else
    let list -> [first next] in
    let first -> [name2 _] in
    if !strcmp name name2 then
      mutate first <- [_ alias]
    else
      ModifyFieldAlias next name alias
;;

fun IniOtherFields (fieldsList) =
  if fieldsList == nil then
    nil
  else
    let fieldsList -> [[name _] next] in
      (name::""::nil)::(IniOtherFields next)
;;

fun RefreshListTab (list, i) =
  if list == nil then 
    0
  else
    let list -> [ [name [alias _]] next] in
    (
      _ADDlistTabItem DBotherFieldsList i i name;
      _SETlistTabItem DBotherFieldsList i 1 alias;
      RefreshListTab next i+1
    )
;;



fun cbSelSQLtable (oText, param, ind, table) =
  if TableChanged then
    let SqlRequest DB "GET_COLUMNS" (SQL_NIL table)::nil -> fieldsList in
    (
      set OtherFields = IniOtherFields fieldsList;
      _RSTlistTab DBotherFieldsList;
      _SETtext DBotherFieldsAlias "";
      _SETtext DBotherFieldsAliasLabel (_locEditor "DB_OTHER_FIELDS_ALIAS_LABEL" nil);
      _ENtext DBotherFieldsAlias 0;

      RefreshListTab OtherFields 0;
      
      _RSTcombo Login;
      FillCombo Login fieldsList 0;
      _RSTcombo Email;
      FillCombo Email fieldsList 0;
      _RSTcombo SendEmail;
      FillCombo SendEmail fieldsList 0;
      
      set OldTable = table
     )
   else 
     nil
;;

fun cbLineOkSQLsource (oText, param, text) =
  if DBchanged then
    let SqlDestroy DB -> _ in
    let _GETtext SQLsource -> dbName in
    let _GETcombo SQLtable -> [_ dbTable] in
    let NilToEmptyStr GetODBCInfos dbName "login" -> dbLogin in
    let NilToEmptyStr GetODBCInfos dbName "password" -> dbPassword in
    let SqlCreate _channel dbName dbLogin dbPassword -> db in
    let SqlRequest db "GET_TABLES" nil -> tablesList in
    let _GETcombo SQLtable -> [ind sel] in
    (
      if db != nil then
        _DLGMessageBox _channel EditorWin (_locEditor "DB_CONNEXION_TITLE" nil)(_locEditor "DB_CONNEXION_MESS_OK" nil) 0
      else
        _DLGMessageBox _channel EditorWin (_locEditor "DB_CONNEXION_TITLE" nil)(_locEditor "DB_CONNEXION_MESS_ECHEC" nil) 0;
        
      set DB = db;
      _RSTcombo SQLtable;
      FillCombo SQLtable tablesList 1;
      _SSELcombo SQLtable sel;
      cbSelSQLtable SQLtable nil ind sel;
      set OldDB = dbName;
      0     
    )
  else
    nil
;;

fun IniDBfields (dbName, tableName, otherFields) =
  if DB == nil then
    let NilToEmptyStr GetODBCInfos dbName "login" -> dbLogin in
    let NilToEmptyStr GetODBCInfos dbName "password" -> dbPassword in
      set DB = SqlCreate _channel dbName dbLogin dbPassword
  else
    nil;
  let SqlRequest DB "GET_TABLES" nil -> tablesList in
  let SqlRequest DB "GET_COLUMNS" (SQL_NIL tableName)::nil -> fieldsList in
  (  
    _SETtext SQLsource dbName; 
    _RSTcombo SQLtable;
    FillCombo SQLtable tablesList 0;
    _SSELcombo SQLtable tableName;

    _SETtext DBotherFieldsAlias "";
    _SETtext DBotherFieldsAliasLabel (_locEditor "DB_OTHER_FIELDS_ALIAS_LABEL" nil);

    set OtherFields = otherFields;
    _RSTlistTab DBotherFieldsList;
    RefreshListTab OtherFields 0;
    
    _RSTcombo Login;
    FillCombo Login fieldsList 0;
    _RSTcombo Email;
    FillCombo Email fieldsList 0;
    _RSTcombo SendEmail;
    FillCombo SendEmail fieldsList 0;
    
    set OldDB = dbName;
    set OldTable = tableName;  
  )
;;

fun cbTextChangedOtherFieldsAlias (oText, param) =
  let _GETtext oText -> text in
  (
    mutate nth_list OtherFields Selection <- [_ text::nil];
    _SETlistTabItem DBotherFieldsList Selection 1 text;
    0
  )
;;
  

fun cbListTabSelect (oList, param, line) =
  if line < 0 then
  (
    _ENtext DBotherFieldsAlias 0;
    _SETtext DBotherFieldsAlias "";
    _SETtext DBotherFieldsAliasLabel (_locEditor "DB_OTHER_FIELDS_ALIAS_LABEL" nil)
  )
  else
    let nth_list OtherFields line -> [name [alias _]] in
    (
      set Selection = line;
      _SETtext DBotherFieldsAlias "";
      _SETtext DBotherFieldsAlias alias;
      _ENtext DBotherFieldsAlias 1;
      _SETtext DBotherFieldsAliasLabel strcat name " :"
    )
;;

/*******************************************************************************
 relay actions/events
*******************************************************************************/
fun Getsupp(n) =
 if n == nil || n <= 0 then 
   nil
 else
   ("actionC"::(strcat "relay." itoa n)::nil)::
   ("event"::(strcat "relay." itoa n)::nil)::Getsupp n-1
;;

/*******************************************************************************
 save modifications
 a      -> S      : not used
 b      -> S      : not used
 editor -> Editor : editor
        <- [[S r1] r1] : the dmi contents
*******************************************************************************/
fun cbSave (a, b) =
  /* save parameters in the data bloc */
  let _GETcombo FramerateCombo -> [ _ Sframerate] in
  let _GETcombo WidthCombo -> [ _ Swidth] in
  let _GETcombo QualityCombo -> [ _ Squality] in
  let _GETcombo FreqMulCombo -> [ _ Sfreqmul] in
  let _GETcombo SampleCombo -> [ _ Ssample] in
  let _GETcombo StereoCombo -> [Sstereo _] in
    setDef Ed "ComData" ("FRAMERATE"::Sframerate::nil)::
                        ("WIDTH"::Swidth::nil)::
                        ("QUALITY"::Squality::nil)::
                        ("FREQMUL"::Sfreqmul::nil)::
                        ("SAMPLE"::Ssample::nil)::
                        ("STEREO"::(itoa (Sstereo+1))::nil)::
                        ("PROXYS"::(itoa ((_GETcheck SYCproxyAudio)*100)+((_GETcheck SYCproxyVideo)*10)+((_GETcheck SYCproxyText)))::nil)::nil;                      
  let _GETcombo SQLtable -> [_ dbTable] in 
  let _GETcombo Login -> [_ loginColumn] in
  let _GETcombo Email -> [_ emailColumn] in
  let _GETcombo SendEmail -> [_ sendEmailColumn] in
    setDef Ed "Data" ("rights"::(GetUserRightsList 0))::
                     ("adminLevel"::(_GETtext AdminLevelItem)::nil)::
                     ("SQLsource"::(_GETtext SQLsource)::nil)::
                     ("SQLtable"::dbTable::nil)::
                     ("LoginColumn"::loginColumn::nil)::
                     ("EmailColumn"::emailColumn::nil)::
                     ("SendEmailColumn"::sendEmailColumn::nil)::
                     ("EmailSender"::(_GETtext EmailExpeditor)::nil)::                     
                     ("OtherFields"::(strbuild OtherFields)::nil)::
                     ("nbEventRelay"::(_GETtext nbEventRelay)::nil)::                   
                     nil;
  /* save dmi informations */  
  ("action"::"start"::nil)::
  ("action"::"destroy"::nil)::
  ("action"::"chgLogin"::nil)::
  ("action"::"emailNotification.disable"::nil)::
  ("action"::"emailNotification.enable"::nil)::
  ("event"::"sendMail"::nil)::
  ("actionC"::"show"::nil)::
  ("actionC"::"hide"::nil)::
  ("event"::"entering"::nil)::
  ("eventC"::"in"::nil)::
  ("event"::"out"::nil)::
  ("eventC"::"shown"::nil)::
  ("eventC"::"hidden"::nil)::
  ("eventC"::"ring"::nil)::  
  ("eventC"::"log"::nil)::
  ("actionC"::"call"::"call"::nil)::
  ("actionC"::"answer"::nil)::
  ("zoneC"::"userlist"::"userlist"::nil)::  
  Getsupp atoi _GETtext nbEventRelay  
;;

fun SetUserRightsList (list) =
  if list == nil then
    0
  else
    let list -> [first next] in
    (
      _ADDlist UserTypeList (_GETlistCount UserTypeList) first;
      SetUserRightsList next
    )
;;

fun SetFieldLabels (list, fields) =
  if fields == nil then
    0
  else
    let fields -> [[_ fieldName] nextFields] in
    let list -> [first next] in
    (
      _SETtext fieldName first ;
      SetFieldLabels next nextFields
    ) 
;;

/*******************************************************************************
 load the parameters for a module instance
 p      -> [[S r1] r1] : the dmi contents
 editor -> Editor      : editor
        <- I           : nothing special
*******************************************************************************/
fun cbLoad (p) =
  _RSTlist UserTypeList;
  let getDef Ed "Data" -> data in
  let switchstr data "rights" -> rights in
  let getDef Ed "ComData" -> comData in
  (    
    SetUserRightsList rights;
    /* Load the communication parameters */
    _SSELcombo FramerateCombo getInfo comData "FRAMERATE";
    _SSELcombo WidthCombo getInfo comData "WIDTH";
    _SSELcombo QualityCombo getInfo comData "QUALITY";
     
    _SSELcombo FreqMulCombo getInfo comData "FREQMUL";
    _SSELcombo SampleCombo getInfo comData "SAMPLE";
    _SELcombo StereoCombo (atoi getInfo comData "STEREO")-1;
    
    let getInfo comData "PROXYS" -> proxys in
    let ((atoi proxys)/100) -> a in
    let (((atoi proxys) - (a*100))/10) -> v in
    let ((atoi proxys) - (a*100) - (v*10)) -> t in
    (
      _SETcheck SYCproxyAudio a;
      _SETcheck SYCproxyVideo v;
      _SETcheck SYCproxyText t;
    );
        
    _SETtext AdminLevelItem getInfo data "adminLevel"; 
    let getInfo data "SQLsource" -> sqlSource in
    let getInfo data "SQLtable" -> sqlTable in
    let getInfo data "LoginColumn" -> loginColumn in
    let getInfo data "EmailColumn" -> emailColumn in
    let getInfo data "SendEmailColumn" -> sendEmailColumn in
    let getInfo data "EmailSender" -> emailExpeditorColumn in  
    let strextr getInfo data "OtherFields" -> otherFields in  
    (
      IniDBfields sqlSource sqlTable otherFields;
      _SSELcombo Login loginColumn;      
      _SSELcombo Email emailColumn;      
      _SSELcombo SendEmail sendEmailColumn;      
      _SETtext EmailExpeditor emailExpeditorColumn
    );
    _SETtext nbEventRelay getInfo data "nbEventRelay";        
    0
  )
;; 

/*******************************************************************************
 When the Ok button is clicked, the popup content modify the selection or is 
 added if selection == nil
 but   -> ObjButton : clicked button
 param -> [ObjWin I]: window and selectionn edited 
       <- I         : unused (always 0)
*******************************************************************************/
fun cbClickOk(but, param) =
  let param -> [win selection] in
  (
    _DELlist UserTypeList selection;
    let _GETtext UserTypeField -> name in
    let _GETtext UserRightsField -> rights in
      _ADDlist UserTypeList _GETlistCount UserTypeList strcatn name::" ("::rights::")"::nil; 
    _DSwindow win;
    0
  )
;;

/*******************************************************************************
 When the Cancel button is clicked, the popup is destroyed, its content is lost 
 but   -> ObjButton : clicked button
 param -> [ObjWin I]: window and selectionn edited 
       <- I         : unused (always 0)
*******************************************************************************/
fun cbClickCancel(but, win) =
  _DSwindow win
;;

fun GetNameAndRights (winTitle, selection, name, rights) =  
  let _GETscreenSize -> [wScreen hScreen] in
  let [300 120] -> [w h] in
  let _CRwindow _channel EditorWin (wScreen-w)/2 (hScreen-h)/2 w h WN_MENU winTitle -> win in
  (
    _CRtext _channel win 5 5 w-10 20 ET_ALIGN_LEFT (_locEditor "TYPE_LABEL" nil);
    set UserTypeField = _CReditLine _channel win 5 25 w-10 20 ET_DOWN|ET_AHSCROLL name;
    if selection != nil then
    ( 
      _ENtext UserTypeField 0;
    )
    else
      nil;
    _CRtext _channel win 5 50 w-10 20 ET_ALIGN_LEFT (_locEditor "USER_RIGHTS_LABEL" nil);
    set UserRightsField = _CReditLine _channel win 5 70 w-10 20 ET_DOWN|ET_AHSCROLL rights;
    _CBbutton _CRbutton _channel win 5 95 (w-15)/2 20 0 (_locEditor "OK_BUTTON" nil) @cbClickOk [win selection];
    _CBbutton _CRbutton _channel win 10+(w-15)/2 95 (w-15)/2 20 0 (_locEditor "CANCEL_BUTTON" nil) @cbClickCancel win;
    0
  );            
  0
;;

/*******************************************************************************
 When the add button is clicked, a new kind of users have to be added
 but   -> ObjButton : clicked button
 param -> u0        : unused
       <- I         : unused (always 0)
*******************************************************************************/
fun cbClickAdd(but, param) =
  GetNameAndRights (_locEditor "ADD_WIN_TITLE" nil) nil nil nil;
  0  
;;
  
/*******************************************************************************
 When the add button is clicked, a new kind of users have to be added
 but   -> ObjButton : clicked button
 param -> u0        : unused
       <- I         : unused (always 0)
*******************************************************************************/
fun cbClickDel (but, param) =
  let _GETlist UserTypeList -> [selection _] in 
    _DELlist UserTypeList selection;
  0
;;

/*******************************************************************************
 When the modify button is clicked, a popup allows to edit the selection 
 but   -> ObjButton : clicked button
 param -> u0        : unused
       <- I         : unused (always 0)
*******************************************************************************/
fun cbClickModify (but, param) =
  let _GETlist UserTypeList -> [selection content] in 
  let strfind " (" content 0 -> pos in
  let substr content 0 pos -> name in
  let substr content pos+2 (strlen content)-pos-3 -> rights in
  if selection != nil then
    GetNameAndRights (_locEditor "MODIFY_WIN_TITLE" nil) selection name rights
  else
    nil;
  0
;;


/*******************************************************************************
 Connexion to the DB
 but   -> ObjButton : clicked button
 param -> u0        : unused
       <- I         : unused (always 0)
*******************************************************************************/
fun cbConnexion (but, param) =
  cbLineOkSQLsource nil nil nil/*oText, param, text*/
;;


/*******************************************************************************
  Callback for the communication parameters fields
*******************************************************************************/

/* The following functions are callbacks used by GetAudioParam */
fun cbFreqValue(combo,Param,selnumber,selstring)=
  set Param.FreqMultiplyer= itoa((atoi selstring) / SYCbaseFrequency) 
;;

fun cbSampleValue(combo,Param,selnumber,selstring)=
  set Param.Sample=itoa ((atoi selstring)/8) 
;;

fun cbStereoValue(combo,Param,selnumber,selstring)=
  set Param.Stereo=itoa (selnumber+1)
;;

/* The following functions are callbacks used by GetAudioPAram */
fun cbFrameRateValue(combo,Param,selnumber,selstring)=
  set Param.Framerate=itoa((atoi selstring)*1000) 
;;

fun cbWidthValue(combo,Param,selnumber,selstring)=
  set Param.Width=selstring
;;

fun cbQualityValue(combo,Param,selnumber,selstring)=
  set Param.Quality=selstring
;;


/*******************************************************************************
  Editor resize functions
*******************************************************************************/
fun ResizeOtherFieldsInterface (win, x, y, w, h) =
  _SIZEtext DBotherFieldsLabel w 20 x y;
  _SIZElistTab DBotherFieldsList w h-45 x y+20;
  _SIZEtext DBotherFieldsAliasLabel w/2-5 20 x y+h-20;
  _SIZEtext DBotherFieldsAlias w/2 20 x+w/2 y+h-20;
  0
;;

fun ResizeUserTypeList (win, x, y, w, h) =
  
  _SIZEtext AdminLevelItemLabel w-10 15 x+5 y+h-INFO_SUP_HEIGHT+25;
  _SIZEtext AdminLevelItem w-10 20 x+5 y+h-INFO_SUP_HEIGHT+45;
  
  _SIZEtext FieldNameLabel w-10 20 x+5 y+h-INFO_SUP_HEIGHT-20;
  
  _SIZEbutton AddButton (w-20)/3 20 x+5 y+h-INFO_SUP_HEIGHT;
  _SIZEbutton DelButton (w-20)/3 20 x+(w-20)/3+10 y+h-INFO_SUP_HEIGHT;
  _SIZEbutton ModifyButton (w-20)/3 20 x+2*(w-20)/3+15 y+h-INFO_SUP_HEIGHT;
  _SIZElist UserTypeList w-10 h-INFO_SUP_HEIGHT-40 x+5 y+30;
  _SIZEtext UserTypeLabel w-10 20 x+5 y+10;
  
  
  _SIZEtext InfoSupLabel w-10 15 x+5 y+h-INFO_SUP_HEIGHT+80;
  _SIZEtext SQLsourceLabel (w-20)/3 20 x+5 y+h-INFO_SUP_HEIGHT+100;
  _SIZEtext SQLsource (w-20)/3 20 x+(w-20)/3+10 y+h-INFO_SUP_HEIGHT+100;
  _SIZEbutton SQLconnection (w-20)/3 20 x+2*(w-20)/3+15 y+h-INFO_SUP_HEIGHT+100;
  _SIZEtext SQLtableLabel w/2-15 20 x+5 y+h-INFO_SUP_HEIGHT+125;
  _SIZEcombo SQLtable w/2-15 20 x+w/2+10 y+h-INFO_SUP_HEIGHT+125;
  
  _SIZEtext LoginLabel w/2-15 20 x+5 y+h-INFO_SUP_HEIGHT+150;
  _SIZEcombo Login w/2-15 200 x+w/2+10 y+h-INFO_SUP_HEIGHT+150;

  _SIZEtext EmailLabel w/2-15 20 x+5 y+h-INFO_SUP_HEIGHT+175;
  _SIZEcombo Email w/2-15 200 x+w/2+10 y+h-INFO_SUP_HEIGHT+175;

  _SIZEtext SendEmailLabel w/2-15 20 x+5 y+h-INFO_SUP_HEIGHT+200;
  _SIZEcombo SendEmail w/2-15 200 x+w/2+10 y+h-INFO_SUP_HEIGHT+200;

  _SIZEtext EmailExpeditorLabel w/2-15 20 x+5 y+h-INFO_SUP_HEIGHT+225;
  _SIZEtext EmailExpeditor w/2-15 20 x+w/2+10 y+h-INFO_SUP_HEIGHT+225;

  ResizeOtherFieldsInterface win x+5 y+h-INFO_SUP_HEIGHT+250 w-10 INFO_SUP_HEIGHT-255;
  0
;;


fun cbResizeWin (win, param, w, h) =
  let param -> [x y] in
  (
    ResizeUserTypeList win x y w-x h-y;
    0
  )
;;

fun cbPaint (win, coord) =
  let coord -> [x y] in
  let _GETwindowSizePosition win -> [w h _ _] in 
  (
    _PAINTline win x 0 x h DRAW_SOLID 1 0;
    _PAINTline win 0 270 x 270 DRAW_SOLID 1 0;
    _PAINTline win x (y+h-INFO_SUP_HEIGHT+75) x+w (y+h-INFO_SUP_HEIGHT+75) DRAW_SOLID 1 0;
    _PAINTline win 0 380 x 380 DRAW_SOLID 1 0
  );  
  0 
;;


/*******************************************************************************
  Interface creation functions
*******************************************************************************/
fun CreateOtherFieldsInterface (win, x, y, w, h) =
  set DBotherFieldsLabel = _CRtext _channel win x y w 20 ET_ALIGN_CENTER (_locEditor "DB_OTHER_FIELDS_LABEL" nil);
  set DBotherFieldsList = _CRlistTab _channel win x y+20 w h-45 LV_SINGLESEL|LV_DOWN;
  set DBotherFieldsAliasLabel = _CRtext _channel win x y+h-20 w/2-5 20 ET_ALIGN_LEFT (_locEditor "DB_OTHER_FIELDS_ALIAS_LABEL" nil);
  set DBotherFieldsAlias = _CReditLine _channel win x+w/2 y+h-20 w/2 20 ET_DOWN|ET_AHSCROLL "";
  _ENtext DBotherFieldsAlias 0;
  _CBtext DBotherFieldsAlias @cbTextChangedOtherFieldsAlias nil;
  _ADDlistTabColumn DBotherFieldsList 0/*rang*/ (w-20)/2 ET_ALIGN_LEFT (_locEditor "DB_OTHER_FIELDS_NAME_COLUMN" nil); 
  _ADDlistTabColumn DBotherFieldsList 1/*rang*/ (w-20)/2 ET_ALIGN_LEFT (_locEditor "DB_OTHER_FIELDS_ALIAS_COLUMN" nil);
  _CBlistTabSelect DBotherFieldsList @cbListTabSelect nil;
  0
;;


fun CreateInterface (win, x, y, w, h) =
  if x!=0 then
  (
    _CBwinPaint win @cbPaint [x y];
    _PAINTline win x 0 x h DRAW_SOLID 1 0;
    _PAINTline win 0 270 x 270 DRAW_SOLID 1 0;
    _PAINTline win x (y+h-INFO_SUP_HEIGHT+75) x+w (y+h-INFO_SUP_HEIGHT+75) DRAW_SOLID 1 0;
    
  )
  else
    nil;
    
  _CBwinSize win @cbResizeWin [x y]; 
    
  set UserTypeLabel = _CRtext _channel win x+5 y+10 w-10 20 ET_ALIGN_CENTER (_locEditor "USER_TYPE_LABEL" nil);  
  set UserTypeList = _CRlist _channel win x+5 y+30 w-10 h-40-INFO_SUP_HEIGHT LB_DOWN|LB_VSCROLL;
  set AddButton = _CBbutton _CRbutton _channel win x+5 y+h-INFO_SUP_HEIGHT (w-20)/3 20 0 
                                     (_locEditor "ADD_BUTTON" nil) @cbClickAdd nil;
  set DelButton = _CBbutton _CRbutton _channel win x+(w-20)/3+10 y+h-INFO_SUP_HEIGHT (w-20)/3 20 0 
                                     (_locEditor "DEL_BUTTON" nil) @cbClickDel nil;
  set ModifyButton = _CBbutton _CRbutton _channel win x+2*(w-20)/3+15 y+h-INFO_SUP_HEIGHT (w-20)/3 20 0 
                                         (_locEditor "MODIFY_BUTTON" nil) @cbClickModify nil;
  
  set AdminLevelItemLabel = _CRtext _channel win x+5 y+h-INFO_SUP_HEIGHT+25 w-10 15 ET_ALIGN_LEFT (_locEditor "ADMIN_LEVEL_LABEL" nil);
  set AdminLevelItem = _CReditLine _channel win x+5 y+h-INFO_SUP_HEIGHT+45 w-10 20 ET_DOWN|ET_AHSCROLL "";
  
  set InfoSupLabel = _CRtext _channel win x+5 y+h-INFO_SUP_HEIGHT+80 w-10 20 ET_ALIGN_CENTER (_locEditor "INFO_SUP_LABEL" nil);
  
  set SQLsourceLabel = _CRtext _channel win x+5 y+h-INFO_SUP_HEIGHT+100 (w-20)/3 20 ET_ALIGN_LEFT (_locEditor "SQL_SOURCE_LABEL" nil);
  set SQLsource = _CReditLine _channel win x+(w-20)/3+10 y+h-INFO_SUP_HEIGHT+100 (w-20)/3 20 ET_DOWN|ET_AHSCROLL "";
  set SQLconnection = _CBbutton _CRbutton _channel win x+2*(w-20)/3+15 y+h-INFO_SUP_HEIGHT+100 (w-20)/3 20 0 
                                         (_locEditor "CONNECTION_BUTTON" nil) @cbConnexion nil;
  set SQLtableLabel = _CRtext _channel win x+5 y+h-INFO_SUP_HEIGHT+125 w/2-15 20 ET_ALIGN_LEFT (_locEditor "SQL_TABLE_LABEL" nil);
  set SQLtable = _CRcombo _channel win x+w/2+10 y+h-INFO_SUP_HEIGHT+125 w/2-15 200 CB_NOEDIT "";

  set LoginLabel = _CRtext _channel win x+5 y+h-INFO_SUP_HEIGHT+150 w/2-15 20 ET_ALIGN_LEFT (_locEditor "LOGIN_LABEL" nil);
  set Login = _CRcombo _channel win x+w/2+10 y+h-INFO_SUP_HEIGHT+150 w/2-15 200 CB_NOEDIT "";
 
  set EmailLabel = _CRtext _channel win x+5 y+h-INFO_SUP_HEIGHT+175 w/2-15 20 ET_ALIGN_LEFT (_locEditor "EMAIL_LABEL" nil);
  set Email = _CRcombo _channel win x+w/2+10 y+h-INFO_SUP_HEIGHT+175 w/2-15 200 CB_NOEDIT "";

  set SendEmailLabel = _CRtext _channel win x+5 y+h-INFO_SUP_HEIGHT+200 w/2-15 20 ET_ALIGN_LEFT (_locEditor "SEND_EMAIL_LABEL" nil);
  set SendEmail = _CRcombo _channel win x+w/2+10 y+h-INFO_SUP_HEIGHT+200 w/2-15 200 CB_NOEDIT "";

  set EmailExpeditorLabel = _CRtext _channel win x+5 y+h-INFO_SUP_HEIGHT+225 w/2-15 20 ET_ALIGN_LEFT (_locEditor "EMAIL_EXPEDITOR_LABEL" nil);
  set EmailExpeditor = _CReditLine _channel win x+w/2+10 y+h-INFO_SUP_HEIGHT+225 w/2-15 20 ET_DOWN|ET_AHSCROLL "nobody@nowhere.com";
  
  _CBlineOk SQLsource @cbLineOkSQLsource nil;
  _CBcombo SQLtable @cbSelSQLtable nil;
  
  CreateOtherFieldsInterface win x+5 y+h-INFO_SUP_HEIGHT+250 w-10 INFO_SUP_HEIGHT-255;                            
  0
;;

fun CreateComParamInterface (win, xpos, ypos, w, h) =
  let mkTvideoParam [nil nil nil nil nil ] -> myTvideoParam in
  let mkTaudioParam [nil nil nil nil nil ] -> myTaudioParam in
  let _CRtext _channel win 5 5 w-10 20 ET_ALIGN_LEFT _locEditor "CONFIG" nil -> text in   
  (
    /* Video configuration */
    let 5+xpos -> x in
    let 35+ypos -> y in
    (
      set FramerateCombo = _CRcombo _channel win x (y + 20) 70 400 CB_NOEDIT "1000";
      set WidthCombo = _CRcombo _channel win x (y + 50) 70 400 CB_NOEDIT "32";
      set QualityCombo = _CRcombo _channel win x (y + 80) 70 400 CB_NOEDIT "25";
    
      let _CRtext _channel win x y w-10 20 ET_ALIGN_LEFT (_locEditor "CONFIG_VIDEO" nil) -> text in     
      let _CRtext _channel win (x + 75) (y + 23) w-85 50 ET_ALIGN_LEFT _locEditor "CONFIG_FRAMERATE" nil -> FrameRateText in
      let _CRtext _channel win (x + 75) (y + 53) w-85 50 ET_ALIGN_LEFT _locEditor "CONFIG_WIDTH" nil -> WidthText in
      let _CRtext _channel win (x + 75) (y + 83) w-85 50 ET_ALIGN_LEFT _locEditor "CONFIG_COMPRESSION" nil -> QualityText in
      (
        _ADDcombo FramerateCombo 1 "1000";
        _ADDcombo FramerateCombo 2 "900";
        _ADDcombo FramerateCombo 2 "800";
        _ADDcombo FramerateCombo 2 "700";
        _ADDcombo FramerateCombo 2 "600";
        _ADDcombo FramerateCombo 2 "500";
        _ADDcombo FramerateCombo 2 "400";
        _ADDcombo FramerateCombo 3 "300";
        _ADDcombo FramerateCombo 4 "200";
        _CBcombo FramerateCombo @cbFrameRateValue myTvideoParam;
        _ADDcombo WidthCombo 1 "32";
        _ADDcombo WidthCombo 2 "64";
        _ADDcombo WidthCombo 3 "128";
        _ADDcombo WidthCombo 4 "256";
        _CBcombo WidthCombo @cbWidthValue myTvideoParam;
        _ADDcombo QualityCombo 1 "1";
        _ADDcombo QualityCombo 2 "25";
        _ADDcombo QualityCombo 3 "50";
        _ADDcombo QualityCombo 4 "75";
        _CBcombo QualityCombo @cbQualityValue myTvideoParam;
      );
    );
    
    /* Audio configuration */
    let 5+xpos -> x in
    let 150+ypos -> y in
    (
      set FreqMulCombo = _CRcombo _channel win x (y + 20) 70 400 CB_NOEDIT "5512";
      set SampleCombo = _CRcombo _channel win x (y + 50) 70 400 CB_NOEDIT "8";
      set StereoCombo = _CRcombo _channel win x (y + 80) 70 400 CB_NOEDIT "Mono";
    
      let _CRtext _channel win x y w-10 20 ET_ALIGN_LEFT _locEditor "CONFIG_AUDIO" nil -> text in   
      let _CRtext _channel win (x + 75) (y + 23) w-85 50 ET_ALIGN_LEFT _locEditor "CONFIG_FREQUENCE" nil -> FreqText in
      let _CRtext _channel win (x + 75) (y + 53) w-85 50 ET_ALIGN_LEFT _locEditor "CONFIG_NUMERISATION" nil -> SampleText in
      let _CRtext _channel win (x + 75) (y + 83) w-85 20 ET_ALIGN_LEFT _locEditor "CONFIG_SAMPLE" nil -> StereoText in
      (
        _ADDcombo FreqMulCombo 1 "5512";
        _ADDcombo FreqMulCombo 2 "11024";
        _ADDcombo FreqMulCombo 3 "22048";
        _ADDcombo FreqMulCombo 4 "44096";
        _CBcombo FreqMulCombo @cbFreqValue myTaudioParam;
        _ADDcombo SampleCombo 1 "8";
        _ADDcombo SampleCombo 2 "16";
        _CBcombo SampleCombo @cbSampleValue myTaudioParam;
        _ADDcombo StereoCombo 1 "mono";
        _ADDcombo StereoCombo 2 "stereo";
        _CBcombo StereoCombo @cbStereoValue myTaudioParam;
      );
    );
    
    /* Admin level item name */
    let 5+xpos -> x in
    let 275+ypos -> y in
    (
      let _CRtext _channel win x y w-10 20 ET_ALIGN_LEFT _locEditor "CONFIG_PROXYS" nil -> text in   
      /* Configuration Serveur SCOL "FIREWALL-PROXY". */
      set SYCproxyAudio = _CRcheck _channel win x (y+20) 120 25 CH_TABFOCUS _locEditor "CONFIG_PROXYAUDIO" nil;
      set SYCproxyVideo = _CRcheck _channel win x (y+45) 120 25 CH_TABFOCUS _locEditor "CONFIG_PROXYVIDEO" nil;
      set SYCproxyText =  _CRcheck _channel win x (y+70) 120 25 CH_TABFOCUS _locEditor "CONFIG_PROXYTEXT" nil;
      1
    );
    
    let 5+xpos -> x in
    let 390+ypos -> y in
    (
      let _CRtext _channel win x y w-10 20 ET_ALIGN_LEFT _locEditor "CONFIG_EVENT" nil -> text in   
      /* Configuration Event Relay. */
      set nbEventRelay = _CReditLine _channel win x (y+20) 70 20 ET_DOWN|ET_AHSCROLL|ET_NUMBER "";
      
      1
    )
  );
  
  
  /* Default Configuration . */
  _SSELcombo FramerateCombo "1000";
  _SSELcombo WidthCombo "128";
  _SSELcombo QualityCombo "25";
 
  _SSELcombo FreqMulCombo "11024";
  _SSELcombo SampleCombo "8";
  _SSELcombo StereoCombo "Mono";
 
  _SETcheck SYCproxyAudio 0;
  _SETcheck SYCproxyVideo 0;
  _SETcheck SYCproxyText 1;
  
  _SETtext nbEventRelay "0";
  0
;;




/*******************************************************************************
 main function called when the editor is starting.
 The openDMI function must be called at the end in order to load the data if the
 module has already been edited.
 s -> S : obsolete (unused)
   <- I : nothing special
*******************************************************************************/
fun IniEditor (s) =
  let [550 100+INFO_SUP_HEIGHT] -> [w h] in
  let 200 -> wCol in
  (
    set Ed = _StartEditor _channel nil nil nil w h WN_NORMAL EDITOR_NORMAL @cbLoad @cbSave nil;
    if Ed == nil then
      nil
    else
    (
      set EditorWin = getEditWin Ed;
      CreateComParamInterface EditorWin 0 0 wCol h;
      CreateInterface EditorWin wCol 0 w-wCol h;
      openDMI Ed;
      0
    )
  )
;;