context:  /*	AssignDialog.cpp - Created by Giampiero Caprino
   
   This file is part of Train Director 3
   
   Train Director is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; using exclusively version 2.
   It is expressly forbidden the use of higher versions of the GNU
   General Public License.
   
   Train Director is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with Train Director; see the file COPYING.  If not, write to
   the Free Software Foundation, 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.
   */
  
  using System;
  using wx;
  
  namespace TrainDirPorting {
    public partial class Globals {
      public static Track path_find_station(Vector path, Track headpos) {
        int i;
        Track trk;
  
        for(i = path._size - 1; i >= 0; --i) {
          trk = path.TrackAt(i);
          if(trk == headpos)
            break;
        }
        for(; i >= 0; --i) {
          trk = path.TrackAt(i);
          if(string.IsNullOrEmpty(trk.station) == false)
            return trk;
        }
        return null;
      }
    }
  
    public class AssignDialog : Dialog {
  
      public StaticText m_header;
      public ListCtrl m_list;
      public Button m_assign,
          m_shunt,
          m_assignshunt,
          m_reverseassign,
          m_split,
          m_properties,
          m_cancel;
  
      private Train assign_tr;
      private Train[] assign_list;
      private int nassign;
      private int maxassign;
  
      private static String[] en_titles = new string[] { wxPorting.T("Train"), wxPorting.T("Departure"), wxPorting.T("Platform"),
   				wxPorting.T("Destination"), wxPorting.T("Arrival"), wxPorting.T("Notes"), null };
      private static String[] titles = new string[en_titles.Length];
      private static int[] col_widths = { 60, 60, 40, 150, 80, 80, 0 };
  
      public AssignDialog(Window parent)
        : base(parent, 0, wxPorting.L("Assign rolling stock"),
            Window.wxDefaultPosition, Window.wxDefaultSize,
            WindowStyles.DD_DEFAULT_STYLE, wxPorting.L("Assign rolling stock")) {
        //EVT_BUTTON((int)MenuIDs.ID_ASSIGN, new wx.EventListener(OnAssign));
        //EVT_BUTTON((int)MenuIDs.ID_ASSIGNSHUNT, new wx.EventListener(OnAssignAndShunt));
        //EVT_BUTTON((int)MenuIDs.ID_REVERSEASSIGN, new wx.EventListener(OnReverseAndAssign));
        //EVT_BUTTON((int)MenuIDs.ID_SHUNT, new wx.EventListener(OnShunt));
        //EVT_BUTTON((int)MenuIDs.ID_SPLIT, new wx.EventListener(OnSplit));
        //EVT_BUTTON((int)MenuIDs.ID_PROPERTIES, new wx.EventListener(OnProperties));
        //EVT_UPDATE_UI((int)MenuIDs.ID_LIST, new wx.EventListener(OnUpdate));
  
        //int i;
  
        //if(titles == null)
        //  Globals.localizeArray(ref titles, en_titles);
  
        //BoxSizer row = new BoxSizer(Orientation.wxHORIZONTAL);
        //BoxSizer col = new BoxSizer(Orientation.wxVERTICAL);
  
        //// Erik: Original code => Following line
        //// m_header = new StaticText(this, 0, String(wxPorting.T('M'), 60));
        //m_header = new StaticText(this, 0, String.Format("%60d", 0).replace('0', wxPorting.T('M')));
        //col.Add(m_header, 0,  Direction.wxRIGHT, 5);
        //m_list = new ListCtrl(this, (int)MenuIDs.ID_LIST, Window.wxDefaultPosition,
        //  Window.wxDefaultSize, WindowStyles.LC_REPORT | WindowStyles.LC_HRULES | WindowStyles.LC_SINGLE_SEL);
  
        //col.Add(m_list, 1, Stretch.wxGROW | Direction.wxTOP | Direction.wxBOTTOM, 5);
        
        //row.Add(col, 1, Stretch.wxGROW | Direction.wxALL, 5);
  
        //col = new BoxSizer(Orientation.wxVERTICAL);
  
        //m_assign = new Button(this, (int)MenuIDs.ID_ASSIGN, wxPorting.L("&Assign"));
        //m_assign.SetDefault();
        //col.Add(m_assign, 0, Direction.wxTOP | Stretch.wxGROW, 10);
        //m_shunt = new Button(this, (int)MenuIDs.ID_SHUNT, wxPorting.L("S&hunt"));
        //col.Add(m_shunt, 0, Direction.wxTOP | Stretch.wxGROW, 10);
        //m_assignshunt = new Button(this, (int)MenuIDs.ID_ASSIGNSHUNT, wxPorting.L("Assign&+Shunt"));
        //col.Add(m_assignshunt, 0, Direction.wxTOP | Stretch.wxGROW, 10);
        //m_reverseassign = new Button(this, (int)MenuIDs.ID_REVERSEASSIGN, wxPorting.L("&Reverse+Assign"));
        //col.Add(m_reverseassign, 0, Direction.wxTOP | Stretch.wxGROW, 10);
        //m_split = new Button(this, (int)MenuIDs.ID_SPLIT, wxPorting.L("Sp&lit"));
        //col.Add(m_split, 0, Direction.wxTOP | Stretch.wxGROW, 10);
        //m_properties = new Button(this, (int)MenuIDs.ID_PROPERTIES, wxPorting.L("&Properties"));
        //m_properties.Disable();
        //col.Add(m_properties, 0, Direction.wxTOP | Stretch.wxGROW, 10);
        //m_cancel = new Button(this, (int)wxID_CANCEL, wxPorting.L("&Cancel"));
        //col.Add(m_cancel, 0, Direction.wxTOP | Stretch.wxGROW, 10);
  
        //row.Add(col, 0, Direction.wxALL, 5);
  
        //wx.ListItem listcol = new ListItem();
  
        ////  Insert columns
  
        //for(i = 0; titles[i] != null; ++i) {
        //  listcol.Text = (titles[i]);
        //  m_list.InsertColumn(i, listcol);
        //  m_list.SetColumnWidth(i, col_widths[i]);
        //}
        //SetSizer(row);
        //row.Fit(this);
        //row.SetSizeHints(this);
        //m_header.Label = wxPorting.T("");
      }
  
      ~AssignDialog() {
        Globals.freeLocalizedArray(titles);
      }
  
      private long assign_train_from_dialog() {
        int i = m_list.SelectedItemCount;
  
        if(i != 1)
          return -1;
  
        long l = m_list.GetNextItem(-1, ListCtrl.NEXT.ALL, ListItemState.SELECTED);
  
        if(l >= 0) {
          Globals.assign_train(assign_list[l], assign_tr);
        }
        EndModal(ShowModalResult.OK);
        return l;
      }
  
      public void OnAssign(object sender, Event evt) {
        assign_train_from_dialog();
      }
  
      public void OnAssignAndShunt(object sender, Event evt) {
        long t = assign_train_from_dialog();
        if(t >= 0)
          Globals.shunt_train(assign_list[t]);
      }
  
      public void OnReverseAndAssign(object sender, Event evt) {
        int i = m_list.SelectedItemCount;
  
        if(i != 1)
          return;
  
        long l = m_list.GetNextItem(-1, ListCtrl.NEXT.ALL, ListItemState.SELECTED);
  
        if(l < 0)
          return;
  
        if(!Globals.reverse_train(assign_tr))
          return;
        assign_train_from_dialog();
      }
  
      public void OnShunt(object sender, Event evt) {
        Globals.shunt_train(assign_tr);
        EndModal(ShowModalResult.OK);
      }
  
      public void OnSplit(object sender, Event evt) {
        int l = 0;
  
        if(assign_tr.length != 0) {
          l = Globals.ask_number(wxPorting.T("Split train"), wxPorting.T("Position where to split the train (meters from the head)"));
          if(l < 0)
            return;
        }
        Globals.split_train(assign_tr, l);
        Globals.shunt_train(assign_tr);
        EndModal(ShowModalResult.OK);
      }
  
      public void OnProperties(object sender, Event evt) {
      }
  
      public void OnUpdate(object sender, Event evt) {
        long l = m_list.GetNextItem(-1, ListCtrl.NEXT.ALL, ListItemState.SELECTED);
  
        bool enable = false;
        if(l >= 0)
          enable = true;
  
        m_assign.Enabled = enable; 
        m_assignshunt.Enabled = enable;
        m_reverseassign.Enabled = enable;
      }
  
      private void fill_assign_train_list(Train t, Track station) {
        Track trk = station;
  
        if(string.IsNullOrEmpty(trk.station))
          return;
        assign_tr = t;
  
        nassign = maxassign = 0;
  
gt:       for(t = Globals.schedule; t != null; t = t.next) {