/// <summary>
        /// Constructor
        /// </summary>
        /// <param name="pathname">pathhname to load</param>
        public MainWindow(string pathname)
        {
            InitializeComponent();

            _mainWindowLayout = new MainWindowLayout(this);
            //Deserialize the Options dialog
            defaultConfigPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + defaultConfigDirectory;
            if (true != Deserialize(defaultConfigPath + defaultConfigFile, false))
            {
                _optionsDialog = new OptionDialog();
            }

            _background = new Canvas();
            _mainCanvas = new BackgroundCanvas(this, _background);

            _background.Children.Add(_mainCanvas);

            Content = _mainWindowLayout;
            SetMemberVars();
            SetBackgroundImage();
            _mainCanvas.Background = Brushes.Transparent;
            SizeChanged           += SizeChangedHandler;


            if (null != pathname && pathname.Length > 0)
            {
                _mainCanvas.AddPhotoCollection(pathname, _optionsDialog.MaximumImages);
                //_mainCanvas.AddImageCollection(pathname, _optionsDialog.MaximumImages);
                //CreateGallery(pathname);
            }

            SetPanelVisibility();
        }
        /// <summary>
        /// Top level manager to deserialize a file. Serialization
        /// Serialization can contains (a) Options and optionally
        /// the UI display
        /// </summary>
        /// <param name="serializedFile">File name to deserialize</param>
        /// <param name="doMainCanvas">When true deserialize the UI. False desrerialize only options</param>
        /// <returns></returns>
        public bool Deserialize(string serializedFile, bool doMainCanvas)
        {
            bool returnValue = false;

            if (File.Exists(serializedFile))
            {
                BinaryFormatter formatter = new BinaryFormatter();
                using (FileStream stream = new FileStream(serializedFile, FileMode.Open, FileAccess.Read))
                {
                    try
                    {
                        _optionsDialog = (OptionDialog)formatter.Deserialize(stream);

                        if (true == doMainCanvas)
                        {
                            _background.Children.Clear();
                            BackgroundCanvas oldCanvas = _mainCanvas;
                            _mainCanvas = (BackgroundCanvas)formatter.Deserialize(stream);
                            _mainCanvas.Deserialize(this, _background);
                            _mainCanvas.RebuildTree(_mainCanvas);
                            _background.Children.Add(_mainCanvas);
                            _mainCanvas.Background = Brushes.Transparent;
                            ResetCanvasSizes();
                            _mainCanvas.DistanceCalculationDelegate = oldCanvas.DistanceCalculationDelegate;
                            _mainCanvas.runMdsDelegate = oldCanvas.runMdsDelegate;
                            _mainCanvas.runMdsUpdate   = oldCanvas.runMdsUpdate;
                            oldCanvas   = null;
                            returnValue = true;
                        }
                        else
                        {
                            returnValue = true;
                        }
                    }
                    catch (Exception e)
                    {
                        ErrorText = "Error reading " + serializedFile + " " + e.Message;
                    }
                }
            }

            return(returnValue);
        }
        /// <summary>
        /// Constructor. Typically called by the UI
        /// </summary>
        /// <param name="faceList">List of faces to include</param>
        public DataExchange(List <Face> faceList, Rect dataRect, OptionDialog optionDialog)
        {
            _creationTime = DateTime.UtcNow;
            _elements     = new List <ExchangeElement>();
            _faceList     = faceList;
            bool doDistanceMatrix = true;

            _coordinates       = new double[_faceList.Count, _dim];
            _dataRect          = new Rect(dataRect.X, dataRect.Y, dataRect.Width, dataRect.Height);
            _backEndConfigFile = optionDialog.BackEndConfigFile;

            int idx = 0;

            foreach (Face face in faceList)
            {
                ExchangeElement ele = new ExchangeElement(idx, face.ByteData, face.ImageWidth, face.ImageHeight);
                Point           location;

                if (Face.SelectionStateEnum.ElementSelect == face.Selected ||
                    Face.SelectionStateEnum.ExtendSelectDrag == face.Selected)
                {
                    System.Diagnostics.Debug.Assert(false == face.IsGrouped, "Data exchange found a grouped + Selected face " + face.FileName);
                    ele.State = ExchangeElement.ElementState.Selected;
                }

                if (true == face.IsGrouped)
                {
                    ele.State = ExchangeElement.ElementState.FrozenLocation;
                    location  = face.MyParent.GetPositionRelativeToCanvas();
                }
                else
                {
                    location = face.GetPositionRelativeToCanvas();
                }

                _elements.Add(ele);
                ele.Left             = location.X;
                ele.Top              = location.Y;
                _coordinates[idx, 0] = location.X;
                _coordinates[idx, 1] = location.Y;

                if (null == face.DistanceVector || face.DistanceVector.Count != faceList.Count)
                {
                    doDistanceMatrix = false;
                }
                ++idx;
            }

            if (true == doDistanceMatrix && _faceList.Count > 0)
            {
                _distanceMatrix = new double[_faceList.Count, _faceList.Count];
                idx             = 0;
                foreach (Face face in _faceList)
                {
                    int idxOther = 0;

                    foreach (Face faceOther in faceList)
                    {
                        _distanceMatrix[idx, idxOther++] = face.GetDistanceToFace(faceOther);
                    }
                    ++idx;
                }
            }
        }