private bool deleteRequest = false; // added Dec 2014

        public BasicPageViewEdit()
        {
            this.InitializeComponent();
            Window.Current.SizeChanged += VisualStateChanged;
            PatientIdTextBox.AddHandler(TappedEvent, new TappedEventHandler(PatientIdTextBox_Tapped), true);
            //previousPdi = new TP_PatientReport();
            updatedReport = new TP_PatientReport();
            App.MyAssert(App.CurrentPatient != null); // though elements may be null or empty
            // Some items in NewReport's constructor have been moved to LoadState() here.
            InitiateZones();
            dt = new DispatcherTimer();
            dt.Interval = new TimeSpan(0, 0, 0, 0, 500); // 500 milliseconds
            dt.Tick += dt_Tick;
            incrementPatientID.AddHandler(PointerPressedEvent, new PointerEventHandler(incrementPatientID_PointerPressed), true);
            decrementPatientID.AddHandler(PointerPressedEvent, new PointerEventHandler(decrementPatientID_PointerPressed), true);
            MyZoneButtonItemWidth = "140";

            ToolTip trafficTip = new ToolTip();
            trafficTip.Content = "Connection lag to TriageTrak.  Red if 3+ seconds (or failed), green if < 1/2 second";
            ToolTipService.SetToolTip(BlinkerTopRed, trafficTip);
            ToolTipService.SetToolTip(BlinkerMiddleYellow, trafficTip);
            ToolTipService.SetToolTip(BlinkerBottomGreen, trafficTip);
            ToolTip sendQueueTip = new ToolTip();
            sendQueueTip.Content = "Count of reports queued to send";
            ToolTipService.SetToolTip(CountInSendQueue, sendQueueTip);

// WAS:            discardMenuPopUp = new Popup();
            //discardMenuPopUp.Closed += (o, e) => this.GetParentOfType<AppBar>().IsOpen = false; // When popup closes, close app bar too.
            //discardMenuPopUp.Closed += (o, e) => TopAppBar.IsOpen = false;
            //discardMenuPopUp.Closed += (o, e) => BottomAppBar.IsOpen = false;
            patientID_ConflictStatus.Text = ""; // July 2015, v 5
        }
 public void Add(TP_PatientReport prd1) // Assume caller will clear & reuse prd1, so make a copy of data for queue.
 {
     // Call this after StartWork()
     TP_PatientReport prd2 = new TP_PatientReport(prd1); // deep copy
     TP_SendQueue.reportsToSend.Add(prd2);
     UpdateCountOnReportPage();
     // Once the orginal is copied & the copy queued, the original is treated as read-only
     // NO, CAUSES PROBLEMS:  prd1.Reinitialize(); // moved here to prevent race condition between queueing and clearing.
 }
        /// <summary>
        /// Identical to code in NewReport
        /// </summary>
        /// <param name="pr_"></param>
        private void LoadReportFieldsFromObject(TP_PatientReport pr_)
        {
            // Already cleared controls when we get here.
            SetFirstNameTextBox(pr_.FirstName);
            SetLastNameTextBox(pr_.LastName);
            PatientIdTextBox.Text = pr_.PatientID;
            App.MyAssert(CheckBoxAdult.IsChecked == false);
            App.MyAssert(CheckBoxPeds.IsChecked == false);
            switch (pr_.AgeGroup)
            {
                case "Adult":
                    CheckBoxAdult.IsChecked = true; break;
                case "Youth": //case "Pediatric":
                    CheckBoxPeds.IsChecked = true; break;
                case "Other Age Group (e.g., Expectant)":
                    CheckBoxAdult.IsChecked = CheckBoxPeds.IsChecked = true; break;
                case "Unknown Age Group":
                case "": // Added Feb 2015. May occur if record entry is incomplete, interrupted by webcam capture
                    break;
                default: App.MyAssert(false); break;
            }
            App.MyAssert(CheckBoxMale.IsChecked == false);
            App.MyAssert(CheckBoxFemale.IsChecked == false);
            switch (pr_.Gender)
            {
                case "Male":
                    CheckBoxMale.IsChecked = true; break;
                case "Female":
                    CheckBoxFemale.IsChecked = true; break;
                case "Complex Gender":
                    CheckBoxMale.IsChecked = CheckBoxFemale.IsChecked = true; break;
                case "Unknown":
                case "": // Added Feb 2015. May occur if record entry is incomplete, interrupted by webcam capture
                    break;
                default: App.MyAssert(false); break;
            }
            zoneSelected = pr_.Zone;
            if (zoneSelected != "") // Test for empty string added Feb 2015. May occur if record entry is incomplete, interrupted by webcam capture 
                ZoneSelect(zoneSelected);

            // Empty fields with hints are already showing hints.  But should we override:
            // We have earlier, during clearing, moved focus away from Notes and Captions.
            if (pr_.Comments != "")
            {
                Notes.Text = pr_.Comments;
                Notes.Focus(FocusState.Programmatic); // Will repaint font as black
            }
#if SUPERCEDED_RELEASE_7_BUT_COULD_REVIVE_AS_HIDDEN_FIELD
            if (pr_.ImageCaption != "")
            {
                SetCaptionTextBox(pr_.ImageCaption);
                GiveCaptionFocus();
            }
#endif
            App.CurrentPatient.ImageCaption = pr_.ImageCaption; // whether empty or not
            /* TO DO.  Note - consider moving practice mode checkbox to settings:
            if (pr_.PatientID.StartsWith("Prac"))
                SetCheckBoxPracticeMode(true); */
        }
        /// <summary>
        /// Identical to code in NewReportPage.  When called, the PatientReport.SendCode has already been updated with the desired value.
        /// </summary>
        /// <param name="pr_"></param>
        private async Task SaveReportFieldsToObject(TP_PatientReport pr_) //, string IntendToSend)
        {
            if ((bool)CheckBoxAdult.IsChecked && (bool)CheckBoxPeds.IsChecked)
                pr_.AgeGroup = "Other Age Group (e.g., Expectant)"; // pregnant
            else if ((bool)CheckBoxAdult.IsChecked)
                pr_.AgeGroup = "Adult";
            else if ((bool)CheckBoxPeds.IsChecked)
                pr_.AgeGroup = "Youth";
            else
                pr_.AgeGroup = "Unknown Age Group";

            //string _gender;
            if ((bool)CheckBoxMale.IsChecked && (bool)CheckBoxFemale.IsChecked)
                pr_.Gender = "Complex Gender"; // pregnant
            else if ((bool)CheckBoxMale.IsChecked)
                pr_.Gender = "Male";
            else if ((bool)CheckBoxFemale.IsChecked)
                pr_.Gender = "Female";
            else
                pr_.Gender = "Unknown";


            // User editable fields:
            pr_.FirstName = SyncAndGetFirstNameTextBox();
            pr_.LastName = SyncAndGetLastNameTextBox();
            pr_.Comments = Notes.Text;
            // Other fields:
            /* Now done by separate GetOrgAndDeviceData() call:
                        CultureInfo provider = CultureInfo.InvariantCulture;
                        pr_.WhenLocalTime = (DateTimeOffset.Now).ToString("yyyy-MM-dd HH:mm:ss K", provider);
                        pr_.Timezone = GetTimeZoneAbbreviation(); */
            //pr_.SentCode = IntendToSend; //"Q", eventually "Y".  Will have suffix if edit+resend
            pr_.PatientID = PatientIdTextBox.Text; // includes prefix
            pr_.Zone = zoneSelected;
            pr_.nPicCount = 0;  // Actual 0 or 1 determination will be done at beginning of WriteXML
            /* Now done by separate GetOrgAndDeviceData() call:
                        pr_.EventShortName = App.CurrentDisaster.EventShortName;
                        pr_.EventName = App.CurrentDisaster.EventName; // w/o suffix
                        pr_.EventType = App.CurrentDisaster.EventType; // can be used to create suffix */
            pr_.ImageName = pr_.FormatImageName();
            pr_.ImageWriteableBitmap = App.CurrentPatient.ImageWriteableBitmap;
            pr_.ImageEncoded = await pr_.FormatImageEncoded(); // derive base64 from updatedReport.ImageWriteableBitmap
#if SUPERCEDED_RELEASE_7
            pr_.ImageCaption = SyncAndGetCaptionTextBox();
#endif
            pr_.ImageCaption = App.CurrentPatient.ImageCaption;
        }
        private async Task SendClickImpl(TP_PatientReport pr)
        {
            App.MyAssert(pr.ObjSentCode.IsValid());
            bool newPrObject = false;
            if (pr.ObjSentCode.GetCodeWithoutVersion() == "Y")
            {
                newPrObject = true;
                // Mark existing record as superceded (we can use copied fields in new record to get the parameter values we need)
                await App.PatientDataGroups.UpdateSendHistory(pr.PatientID, pr.ObjSentCode.GetVersionCount(), pr.SentCode, true /*superceded*/);
                pr.ObjSentCode.BumpVersion();
            }
            // else "N" or error.  to do: better treatment for error cases "Xn".

            if(deleteRequest)
                pr.ObjSentCode.ReplaceCodeKeepSuffix("QD"); // New Dec 2014
            else
                pr.ObjSentCode.ReplaceCodeKeepSuffix("Q");
            await SaveReportFieldsToObject(pr);
            await pr.DoSendEnqueue(newPrObject); // cleanup image fields, generate lp2 content, save it as file, then call SendQueue.Add, 
        }
        private async void Send_Click(object sender, RoutedEventArgs e)
        {
            // In first release, user cannot edit or change patient ID.
            // Send button should be disabled if no change was made, unless not yet sent [to do?]
            // Unlike with Win7, the PatientReport lists here can contain the same patientID multiple times, because the list will contain all messages, not just the latest.
            // New flag "superceded" keep track of that.
            // However, if there's an error, redo will use the same object, not a new one.
            App.MyAssert(App.PatientDataGroups != null);
            if (!await ConfirmOrReviseGender())
                return;
            if (!await ConfirmOrReviseAgeGroup())
                return;

            LastSentMsg.Text = "";
            //LastSentMsg.Visibility = Visibility.Collapsed;
            progressBarSending.Visibility = Visibility.Visible;

            if (Notes.Text == NOTES_TEXT_HINT) // Must match string in XAML too
                Notes.Text = "";
#if SUPERCEDED_RELEASE_7
            if (SyncAndGetCaptionTextBox() == CAPTION_TEXT_HINT) // Must match string in XAML too
                SetCaptionTextBox("");
#endif
            App.MyAssert(updatedReport.ObjSentCode.IsValid());
            if (updatedReport.ObjSentCode.GetCodeWithoutVersion() == "Y")
            {
                TP_PatientReport updatedReportNewInstance = new TP_PatientReport(updatedReport); // create a new object for each report,
                // that will be passed through the queue and be reference from the _outbox and _allstations lists.
                await SendClickImpl(updatedReportNewInstance);
            }
            else
            {
                // "N" or error.  to do: better treatment for error cases "Xn".
                await SendClickImpl(updatedReport); // recycle existing object
            }

            // Replaced by UpdateSendHistory on dequeue: await updatedReport.DoSendPart2(); // Update outbox and allstations in both memory and local storage.  As well as sorted/filtered version in memory

            ClearEntryAll(); //Clear_Entry_Click(sender, e); // Unlike New Report, DOES NOT increment patient ID
            // Save incremented value, with prefix removed.  Remembers it to OtherSettings.xml, and clears App.CurrentPatient:
            // NO: await updatedReport.DoSendPart3(PatientIdTextBox.Text.Remove(0, App.OrgPolicy.OrgPatientIdPrefixText.Length));
            //Bad idea, the object is being enqueued: updatedReport.Clear(); // forget about this patient, start anew
            App.CurrentPatient.Clear(); // not a good idea to null pdi or CurrentPatient, since we're not reinstantiating it elsewhere.
            App.ReportAltered = false; // reset

            Int32 count;
            while (true)
            {
                count = TP_SendQueue.reportsToSend.Count();
                if (count > 0)
                    // was: LastSentMsg.Text = "Reports waiting to send:  " + count;
                    AdjustLastSentMsgText("Reports waiting to send:  " + count);
                else
                {
                    AdjustProgressBarVisibility(Visibility.Collapsed);  // was: progressBarSending.Visibility = Visibility.Collapsed;
                    AdjustLastSentMsgText("Sent"); // was: LastSentMsg.Text = "Sent";
                }

                await Task.Delay(2000); // see message for 2 seconds
                if (count == 0 || count <= TP_SendQueue.reportsToSend.Count()) // if count doesn't decrease after 2 seconds, then don't wait further in this loop
                    break;
            }
            AdjustProgressBarVisibility(Visibility.Collapsed); // was: progressBarSending.Visibility = Visibility.Collapsed;
            ShowTitleAndSentTimeAsUnaltered(); // reset fields from red to white, restore original title
            EntryEachIsEnabled(false); // disable entry fields
        }
        /// <summary>
        /// Populates the page with content passed during navigation.  Any saved state is also
        /// provided when recreating a page from a prior session.
        /// </summary>
        protected override async void LoadState(LoadStateEventArgs e)
        {
            InitiateZones();
            // was before Release 2:
            // if (!String.IsNullOrEmpty(App.CurrentPatient.Zone)) // This test may need refinement
            //    LoadReportFieldsFromObject(pr);
            if (latestNavigation.NavigationMode == NavigationMode.Back) // probably back from webcam
            {
                // Assume there's content to reload
                pr = App.CurrentPatient;
                LoadReportFieldsFromObject(pr);
            }
            await PatientID_TextChanged(); // added July 2015. Will check if initial ID is already used, i.e., reported for current event. If so, colorize fields
            pageSubtitle.Text = " " + App.CurrentDisaster.EventName; // TO DO: binding in XAML instead of here?  Add space to separate from icon
            if (App.CurrentDisaster.TypeIconUri.Length > EMBEDDED_FILE_PREFIX.Length)
            {
                eventTypeImage.Source = new BitmapImage(new Uri(App.CurrentDisaster.TypeIconUri));
                // Tried XAML binding, didn't work:                 <Image x:Name="eventTypeImage" Source="{Binding CurrentDisasterEventTypeIcon}" Width="40" VerticalAlignment="Top"/>
                // WAS before next call added: MyZoneButtonItemWidth = "140";
            }
            AdjustZoneButtonWidth();

            UpdateImageLoad();
#if IS_THIS_NECESSARY
            if (firstTime)
            {
                firstTime = false;
                UpdateStoryBoard();
            }
#endif
            // Not needed: base.LoadState(e);
        }
 public void CopyFrom(TP_PatientReport pdi)
 {
     WhenLocalTime = pdi.WhenLocalTime;
     Timezone = pdi.Timezone;
     WhenLocalTimeMsg1 = pdi.WhenLocalTimeMsg1;
     TimezoneMsg1 = pdi.TimezoneMsg1;
     DateEDXL = pdi.DateEDXL;
     DistributionID_EDXL = pdi.DistributionID_EDXL;
     SenderID_EDXL = pdi.SenderID_EDXL;
     DeviceName = pdi.DeviceName;
     UserNameForDevice = pdi.UserNameForDevice;
     UserNameForWebService = pdi.UserNameForWebService;
     OrgName = pdi.OrgName;
     OrgID = pdi.OrgID;
 // These are used to fabricate distribution ID, but do we really need them separately?
 // private String _orgNPI = string.Empty;
 // ditto orgPhone, orgEmail
     SentCode = pdi.SentCode; // also fills in OrgSentCode
     Superceded = pdi.Superceded;
     PatientID = pdi.PatientID;
     Zone = pdi.Zone;
     Gender = pdi.Gender;
     AgeGroup = pdi.AgeGroup;
     FirstName = pdi.FirstName;
     LastName = pdi.LastName;
     nPicCount = pdi.nPicCount;
     EventShortName = pdi.EventShortName;
     EventName = pdi.EventName; // w/o suffix
     EventType = pdi.EventType; // suffix
     ImageName = pdi.ImageName;
     ImageEncoded = pdi.ImageEncoded;
     ImageCaption = pdi.ImageCaption;
     ImageWriteableBitmap = pdi.ImageWriteableBitmap;
     Comments = pdi.Comments;
     WhyNoPhotoReason = pdi.WhyNoPhotoReason;
     FullNameEDXL_and_LP2 = pdi.FullNameEDXL_and_LP2;
 }
        /// <summary>
        /// Populates the page with content passed during navigation.  Any saved state is also
        /// provided when recreating a page from a prior session.
        /// </summary>
        protected override async void LoadState(LoadStateEventArgs e) // Glenn added async here, might not turn out well
        {
            // Differs from NewReport:
            if (e.NavigationParameter.ToString() == "pageViewEditReport")
            {
                // Coming from web cam.  We already have what we need in App.CurrentPatient
                //suppressMarkingAsAltered = false;
                updatedReport = App.CurrentPatient;
                await Load_Entry(updatedReport);
            }
            else
            {   // navigation parameter is the unique Id associated with search results in the the flip view
                //suppressMarkingAsAltered = true;
                ShowTitleAndSentTimeAsUnaltered(); // need this?
                ClearEntryAll(); //ClearEntryExceptPatientID(); // Will need more work when we're reloading state from suspend
                string UniqueID = e.NavigationParameter.ToString();

                bool foundPatient = false;
                foreach (var pr_ in App.PatientDataGroups.GetOutbox())
                {
                    if (pr_.WhenLocalTime == UniqueID)
                    {
                        foundPatient = true;
                        App.CurrentPatient = pr_;
                        updatedReport = pr_;
                        await Load_Entry(updatedReport);
                        break;
                    }
                }
                if (!foundPatient)
                {
                    // was before PLUS v34: App.MyAssert(false);
                    string msg =
                        "Sorry, internal problem: TriagePic can't find this report to edit in the Outbox list.\n" +
                        "Conjecture: due to starting an edit, but leaving and then coming back through search?\n" +
                        "This is a known problem of this release of TriagePic for Windows Store.\n" +
                        "If problem persists, consider editing such reports at the TriageTrak web site.";
                    var dialog1 = new MessageDialog(msg);
                    var t1 = dialog1.ShowAsync(); // Assign to t1 to suppress compiler warning
                    return;
                }
            }
            if (App.ReportAltered)
                ShowTitleAndSentTimeAsAltered();

            pageSubtitle.Text = " " + App.ViewedDisaster.EventName; // App.CurrentDisasterEventName; // TO DO: binding in XAML instead of here?  Add space to separate from icon
            ViewedDisasterEventTypeIcon = App.ViewedDisaster.GetIconUriFromEventType();
            // Momentarily shift focus to notes and caption to force text font to the correct color (either black or gray) for contents
            Notes_GotFocusImpl(); // These don't affect the focus, only the content and font color.
            Notes_LostFocusImpl();
#if SUPERCEDED_RELEASE_7
            Caption_GotFocusImpl(); // These don't affect the focus, only the content and font color.
            Caption_LostFocusImpl();
#endif
#if WIN80_CODE_NO_LONGER_WORKS
            // Didn't work in 8.1, returns false.  Maybe because called from LoadState:
            // bool debug = Notes.Focus(FocusState.Programmatic);
            // This was suggested in forum as solution, but still didn't work:
            bool debug = false;
            await Dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
                {
                    debug = Notes.Focus(FocusState.Programmatic); // or maybe .Keyboard
                });
            App.MyAssert(debug);
            GiveCaptionFocus();
            PatientIdTextBox.Focus(FocusState.Programmatic); // Didn't work... and for View/Edit makes more sense to put on Comment aka Notes field
#endif

            // In common with NewReport:
            if (ViewedDisasterEventTypeIcon.Length > EMBEDDED_FILE_PREFIX.Length)
            {
                eventTypeImage.Source = new BitmapImage(new Uri(ViewedDisasterEventTypeIcon));
                // Tried XAML binding, didn't work:                 <Image x:Name="eventTypeImage" Source="{Binding CurrentDisasterEventTypeIcon}" Width="40" VerticalAlignment="Top"/>
                // WAS before next call added: MyZoneButtonItemWidth = "140";
            }
            AdjustZoneButtonWidth();

            UpdateImageLoad();
            //suppressMarkingAsAltered = false;
        }
 private async Task GetFreshImage()
 {
     // Maybe we should introduce App.EditingPatient, rather than reusing CurrentPatient
     await SaveReportFieldsToObject(App.CurrentPatient); //, ""); // Leave IntendToSend empty until "Send" button pressed.
     updatedReport = App.CurrentPatient; // Probably not strictly necessary, will go out of scope soon.
     App.MyAssert(App.CurrentPatient.SentCode != "" && !App.CurrentPatient.ObjSentCode.IsQueued()); // This MUST be true because WebcamPage will be checking it to decide to come back here, instead of to NewReport
     this.Frame.Navigate(typeof(WebcamPage));
     // if fresh image is gotten, App.ReportAltered will be true for benefit of MarkAsAltered
 }
 private async void patientImage_Tapped(object sender, TappedRoutedEventArgs e)
 {
     await SaveReportFieldsToObject(App.CurrentPatient, ""); // Not yet sent
     pr = App.CurrentPatient; // Probably not necessary since pr will be going out of scope, but just in case.
     this.Frame.Navigate(typeof(WebcamPage));
 }
        /*
 <Rectangle x:Name="BlinkerTopRed" x:FieldModifier="public" Height="15" Width="15" Fill="DarkRed" />
                        <Rectangle x:Name="BlinkerMiddleYellow" x:FieldModifier="public" Margin="0,4" Height="15" Width="15" Fill="DarkGoldenrod" />
                        <Rectangle x:Name="BlinkerBottomGreen" x:FieldModifier="public" Height="15" Width="15" Fill="DarkGreen" />
                        <TextBlock x:Name="CountInSendQueue" x:FieldModifier="public" Height="30" Width="40" Margin="0,10,0,0" FontSize="18" TextAlignment="Center" FontWeight="Bold" /> */
#endif
        public BasicPageNew()
        {
            this.InitializeComponent();
            Window.Current.SizeChanged += VisualStateChanged;
            PatientIdTextBox.AddHandler(TappedEvent, new TappedEventHandler(PatientIdTextBox_Tapped), true);
            // pr == null in constructor
            pr = new TP_PatientReport(); // though elements may be null or empty
            App.MyAssert(App.CurrentPatient != null);

            if (String.IsNullOrEmpty(App.CurrentPatient.PatientID))
                App.CurrentPatient.PatientID = App.CurrentOtherSettings.CurrentNewPatientNumber; // reload.  Probably not good enough.
            App.MyAssert(!String.IsNullOrEmpty(App.CurrentPatient.PatientID)); // Should be loaded from OtherSettings.xml, or at generation associated with that.
            /// Maybe not: PatientIdTextBox.MaxLength = Convert.ToInt32(App.OrgPolicy.GetPatientIDMaxTextBoxLength());
            if (!String.IsNullOrEmpty(App.CurrentPatient.Zone)) // This test may need refinement
            {
                pr = App.CurrentPatient;
                // Move to LoadState, needs to be after InitiateZones call: LoadReportFieldsFromObject(pr); // may not be the way to go in long term
            }
            else
            {
                PatientIdTextBox.Text = App.CurrentPatient.PatientID; // cheap initialization
                // This does not fire TextChanged, so we'll force it later in LoadState
            }
            // We'll check if ID is already in use later, in LoadState

            //Move to LoadState: InitiateZones();

            App.ViewedDisaster.Clear(); // a little housecleaning for the benefit of ViewEditReportPage
            dt = new DispatcherTimer();
            dt.Interval = new TimeSpan(0,0,0,0,500); // 500 milliseconds
            dt.Tick += dt_Tick;
            incrementPatientID.AddHandler(PointerPressedEvent, new PointerEventHandler(incrementPatientID_PointerPressed), true);
            decrementPatientID.AddHandler(PointerPressedEvent, new PointerEventHandler(decrementPatientID_PointerPressed), true);
            MyZoneButtonItemWidth = "140";

            ToolTip trafficTip = new ToolTip();
            trafficTip.Content = "Connection lag to TriageTrak.  Red if 3+ seconds (or failed), green if < 1/2 second";
            ToolTipService.SetToolTip(BlinkerTopRed, trafficTip);
            ToolTipService.SetToolTip(BlinkerMiddleYellow, trafficTip);
            ToolTipService.SetToolTip(BlinkerBottomGreen, trafficTip);
            ToolTip sendQueueTip = new ToolTip();
            sendQueueTip.Content = "Count of reports queued to send";
            ToolTipService.SetToolTip(CountInSendQueue, sendQueueTip);
            LastSentMsg.DataContext = this;
            patientID_ConflictStatus.Text = ""; // July 2015, v 5.  Clear design-time string "[conflict status]"
        }
        private async void Send_Click(object sender, RoutedEventArgs e)
        {
            App.MyAssert(App.PatientDataGroups != null);
            if (!await ConfirmOrReviseGender())
                return;
            if (!await ConfirmOrReviseAgeGroup())
                return;

            AdjustProgressBarVisibility(Visibility.Visible);
            if (Notes.Text == NOTES_TEXT_HINT) // Must match string in XAML too
                Notes.Text = "";
            if (App.RosterNames != "")
                Notes.Text += "\nRoster at Station:\n" + App.RosterNames; // DON'T DO THIS FOR RE-SEND... wait til we handle rostering smarter. 
#if SUPERCEDED_RELEASE_7
            if (SyncAndGetCaptionTextBox() == CAPTION_TEXT_HINT) // CAPTION_TEXT_HINT must match string in XAML too
                SetCaptionTextBox("");
#endif
            await SaveReportFieldsToObject(pr, "Q"); // IntendToSend
            TP_PatientReport pr2 = new TP_PatientReport(pr); // create a new object for each report, that will be passed through the queue
            // and be reference from the _outbox and _allstations lists.
            await pr2.DoSendEnqueue(true); // cleanup image fields, generate lp2 content, save it as file, then call SendQueue.Add, 

            // Move to later: await pr.DoSendPart2(); // Update outbox and allstations in both memory and local storage.  As well as sorted/filtered version in memory

            Clear_Entry_Click(sender, e); // Also increments patient ID
            // Save incremented value, with prefix removed.  Remembers it to OtherSettings.xml, and clears App.CurrentPatient:
            await pr2.DoSendPart3(PatientIdTextBox.Text.Remove(0, App.OrgPolicy.OrgPatientIdPrefixText.Length));


#if DIDNT_WORK
            double op = 100.0;
            while(true)
            {
                op -= 0.00001;
                LastSentMsg.Opacity = op;
                if(op <= 0.0)
                    break;
            }
            LastSentMsg.Opacity = 100.0;
#endif

            Int32 count;
            while (true)
            {
                count = TP_SendQueue.reportsToSend.Count();
                // Tried subsituting data-bound LastSentMessage for LastSentMsg.Text below, but didn't help with bindings that change with visual state
                if (count > 0)
                    AdjustLastSentMsgText("Reports waiting to send:  " + count);
                else
                {
                    AdjustProgressBarVisibility(Visibility.Collapsed);
                    AdjustLastSentMsgText("Sent");
                }

                await Task.Delay(2000); // see message for 2 seconds
                if (count == 0 || count <= TP_SendQueue.reportsToSend.Count()) // if count doesn't decrease after 2 seconds, then don't wait further in this loop
                    break;
            }
            AdjustProgressBarVisibility(Visibility.Collapsed);
            // Maybe not: if(!LastSentMsg.Text.StartsWith("Reports waiting to send")) // Let count of waiting reports persist
            /* was: LastSentMsg.Text */
            AdjustLastSentMsgText("");
        }
        /// <summary>
        /// Populates the page with content passed during navigation.  Any saved state is also
        /// provided when recreating a page from a prior session.
        /// </summary>
        /// <param name="navigationParameter">The parameter value passed to
        /// <see cref="Frame.Navigate(Type, Object)"/> when this page was initially requested.
        /// </param>
        /// <param name="pageState">A dictionary of state preserved by this page during an earlier
        /// session.  This will be null the first time a page is visited.</param>
        protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
        {
            InitiateZones();
            // was before Release 2:
            // if (!String.IsNullOrEmpty(App.CurrentPatient.Zone)) // This test may need refinement
            //    LoadReportFieldsFromObject(pr);
            if (latestNavigation.NavigationMode == NavigationMode.Back) // probably back from webcam
            {
                // Assume there's content to reload
                pr = App.CurrentPatient;
                LoadReportFieldsFromObject(pr);
            }
            pageSubtitle.Text = " " + App.CurrentDisaster.EventName; // TO DO: binding in XAML instead of here?  Add space to separate from icon
            if(App.CurrentDisaster.TypeIconUri.Length > EMBEDDED_FILE_PREFIX.Length)
            {
                eventTypeImage.Source = new BitmapImage(new Uri(App.CurrentDisaster.TypeIconUri));
#if MAYBE
                string path = App.CurrentDisasterEventTypeIcon.Substring(prefix.Length);
                path += Windows.ApplicationModel.Package.Current.InstalledLocation.ToString();
                BitmapImage img = new BitmapImage();
                var uri = new Uri(path);
                img.UriSource = uri;
                eventTypeImage.Source = img;
#endif
                // Tried XAML binding, didn't work:                 <Image x:Name="eventTypeImage" Source="{Binding CurrentDisasterEventTypeIcon}" Width="40" VerticalAlignment="Top"/>
                MyZoneButtonItemWidth= "140";
            }

            UpdateImageLoad();
            if (firstTime)
            {
                firstTime = false;
                UpdateStoryBoard();
            }
        }
        /// <summary>
        /// Populates the page with content passed during navigation.  Any saved state is also
        /// provided when recreating a page from a prior session.
        /// </summary>
        /// <param name="navigationParameter">The parameter value passed to
        /// <see cref="Frame.Navigate(Type, Object)"/> when this page was initially requested.
        /// </param>
        /// <param name="pageState">A dictionary of state preserved by this page during an earlier
        /// session.  This will be null the first time a page is visited.</param>
        protected override async void LoadState(Object navigationParameter, Dictionary<String, Object> pageState) // Glenn added async here, might not turn out well
        {
            // Differs from NewReport:
            if ((string)navigationParameter == "pageViewEditReport")
            {
                // Coming from web cam.  We already have what we need in App.CurrentPatient
                //suppressMarkingAsAltered = false;
                updatedReport = App.CurrentPatient;
                await Load_Entry(updatedReport);
            }
            else
            {   // navigation parameter is the unique Id associated with search results in the the flip view
                //suppressMarkingAsAltered = true;
                ShowTitleAndSentTimeAsUnaltered(); // need this?
                ClearEntryAll(); //ClearEntryExceptPatientID(); // Will need more work when we're reloading state from suspend
                string UniqueID = (string)navigationParameter;

                bool foundPatient = false;
                foreach (var pr_ in App.PatientDataGroups.GetOutbox())
                {
                    if (pr_.WhenLocalTime == UniqueID)
                    {
                        foundPatient = true;
                        App.CurrentPatient = pr_;
                        updatedReport = pr_;
                        await Load_Entry(updatedReport);
                        break;
                    }
                }
                if (!foundPatient)
                {
                    // was before PLUS v34: App.MyAssert(false);
                    string msg =
                        "Sorry, internal problem: TriagePic can't find this report to edit in the Outbox list.\n" +
                        "Conjecture: due to starting an edit, but leaving and then coming back through search?\n" +
                        "This is a known problem of this release of TriagePic for Windows Store.\n" +
                        "If problem persists, consider editing such reports at the TriageTrak web site.";
                    var dialog1 = new MessageDialog(msg);
                    var t1 = dialog1.ShowAsync(); // Assign to t1 to suppress compiler warning
                    return;
                }
            }
            if (App.ReportAltered)
                ShowTitleAndSentTimeAsAltered();

            pageSubtitle.Text = " " + App.ViewedDisaster.EventName; // App.CurrentDisasterEventName; // TO DO: binding in XAML instead of here?  Add space to separate from icon
            ViewedDisasterEventTypeIcon = App.ViewedDisaster.GetIconUriFromEventType();
            // Momentarily shift focus to notes and caption to force text font to the correct color (either black or gray) for contents
            Notes_GotFocusImpl(); // These don't affect the focus, only the content and font color.
            Notes_LostFocusImpl();
            Caption_GotFocusImpl(); // These don't affect the focus, only the content and font color.
            Caption_LostFocusImpl();
#if WIN80_CODE_NO_LONGER_WORKS
            // Didn't work in 8.1, returns false.  Maybe because called from LoadState:
            // bool debug = Notes.Focus(FocusState.Programmatic);
            // This was suggested in forum as solution, but still didn't work:
            bool debug = false;
            await Dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
                {
                    debug = Notes.Focus(FocusState.Programmatic); // or maybe .Keyboard
                });
            App.MyAssert(debug);
            GiveCaptionFocus();
            PatientIdTextBox.Focus(FocusState.Programmatic); // Didn't work... and for View/Edit makes more sense to put on Comment aka Notes field
#endif

            // In common with NewReport:
            if(ViewedDisasterEventTypeIcon.Length > EMBEDDED_FILE_PREFIX.Length)
            {
                eventTypeImage.Source = new BitmapImage(new Uri(ViewedDisasterEventTypeIcon));
#if MAYBE
                string path = App.CurrentDisasterEventTypeIcon.Substring(prefix.Length);
                path += Windows.ApplicationModel.Package.Current.InstalledLocation.ToString();
                BitmapImage img = new BitmapImage();
                var uri = new Uri(path);
                img.UriSource = uri;
                eventTypeImage.Source = img;
#endif
                // Tried XAML binding, didn't work:                 <Image x:Name="eventTypeImage" Source="{Binding CurrentDisasterEventTypeIcon}" Width="40" VerticalAlignment="Top"/>
                MyZoneButtonItemWidth= "140";
            }

            UpdateImageLoad();
            //suppressMarkingAsAltered = false;
#if VARIOUS_ATTEMPTS_TRIED_FAILED_TO_SET_FOCUS_IN_NOTES
            /*await */Dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
            {
                //Notes.Focus(FocusState.Programmatic);
                Notes.Focus(FocusState.Keyboard);
            });

            Notes.Focus(FocusState.Pointer);

            await Dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
                {
                    Notes.Focus(Windows.UI.Xaml.FocusState.Keyboard);
                });
#endif
#if SET_FOCUS_IN_NOTES_WORKED_BUT_MAYBE_NOT_A_GOOD_IDEA_AFTERALL
// Because we don't really know what field the user might want to edit.
            // Try with hack of surround XAML with ScrollViewer with IsTabStop="true":
            // <ScrollViewer x:Name="hackScrollViewerToSetTextBoxFocus" IsTabStop="true"><Textbox x:Name="Notes" ...></ScrollViewer>
            // Use of ScrollViewer still didn't work by itself, but did with Updatelayout,
            // suggested by http://stackoverflow.com/questions/18121089/remove-focus-on-first-textbox :
            hackScrollViewerToSetTextBoxFocus.UpdateLayout();
            Notes.Focus(FocusState.Programmatic);
            // However, this sets the focus to the start of the text, if text pre-exists; so we'd have to further move it to end.
            // Also, if no text except hint, then setting focus likely gets in the way of hint concept.
            // So ScrollViewer was removed from xaml.
            // See DeleteRemoteToo_Click() below for actual textbox manipulation.
#endif
        }
        public TP_PatientReport() { } // Parameterless constructor required for serializer

        public TP_PatientReport(TP_PatientReport pr)
        {
            CopyFrom(pr);
        }
        /// <summary>
        /// Specific to ViewEditReport, not in NewReport
        /// </summary>
        /// <param name="pr_"></param>
        private async Task/*void*/ Load_Entry(TP_PatientReport pr_)
        {
            Zone_Clear(); // disables SendButton too.  Unlike NewReport, which starts with no zone selected, we'll indicate a selected zone in a moment.
            // First do fields common to NewReport and ViewEditReport:
            LoadReportFieldsFromObject(pr_);
            // Then difference:
            string sentMsg = "";
            if (pr_.ObjSentCode.GetVersionCount() > 1)
                sentMsg = pr_.ObjSentCode.GetVersionSuffixFilenameForm().Substring(1);  // of form " Msg#2" with leading space, which is then removed

            if (pr_.ObjSentCode.IsDoneOK()) // most equivalent to: if (pr_.SentCode.StartsWith("Y"))
            {
                if (sentMsg == "")
                    LastSentMsg.Text = "When";
                else
                    LastSentMsg.Text = sentMsg;
                LastSentMsg.Text += " sent: " + pr_.WhenLocalTime + " " + pr_.Timezone;
            }
            else
            {
                if (sentMsg == "")
                    LastSentMsg.Text = "Not yet sent.";
                else
                    LastSentMsg.Text = sentMsg + " not yet sent.";
            }
            // TO DO: Make this smarter:
            //if (App.CurrentDisasterEventShortName != pr_.EventShortName)
            //    LastSentMsg.Text += "   Current Event Changed!";
            //App.CurrentDisasterEventShortName = pr_.EventShortName;
            //App.CurrentDisasterEventName = pr_.EventName; // w/o suffix
            //App.CurrentDisasterEventType = pr_.EventType; // can be used to create suffix
            App.ViewedDisaster.EventShortName   = pr_.EventShortName;
            App.ViewedDisaster.EventName = pr_.EventName;
            App.ViewedDisaster.EventType = pr_.EventType;
            var Event = new TP_EventsDataItem();
            Event.EventType = pr_.EventType;
            ViewedDisasterEventTypeIcon = Event.GetIconUriFromEventType();
            if (pr_.ImageWriteableBitmap == null)
            {
                if (pr_.ImageEncoded.StartsWith("Assets/")) // Might be Assets/NoPhotoBrown(C17819)(300x225).png
                    pr_.ImageEncoded = "";
                pr_.ImageWriteableBitmap = await CreateImageAsync(pr_.ImageEncoded);
            }
            App.CurrentPatient.ImageWriteableBitmap = pr_.ImageWriteableBitmap; // fake as if just came from web cam
        }
示例#18
0
        private static async Task DoResumeFromTermination()
        {
            // Called after DoStartup.  Organized here by data type.
            // Globals of type string:
            RosterNames = (string)SuspensionManager.SessionState["RosterNames"];
            CurrentSearchQuery = (string)SuspensionManager.SessionState["CurrentSearchQuery"];
            CurrentSearchResultsGroupName = (string)SuspensionManager.SessionState["CurrentSearchResultsGroupName"];
            SearchResultsEventTitleTextBasedOnCurrentFilterProfile = (string)SuspensionManager.SessionState["SearchResultsEventTitleTextBasedOnCurrentFilterProfile"];
            if (String.IsNullOrEmpty(UserWin8Account))
                // May be empty string if PC Settings/Prvacy/"Let apps use my name and account picture" is false
                UserWin8Account = await GetUserWin8Account(); // Regenerate instead of: UserWin8Account = (string)SuspensionManager.SessionState["UserWin8Account"];
            if (String.IsNullOrEmpty(DeviceName))
                DeviceName = GetDeviceName(); // Regenerate instead of: DeviceName = (string)SuspensionManager.SessionState["DeviceName"];
            if (String.IsNullOrEmpty(StorePackageVersionMajorDotMinor))
                StorePackageVersionMajorDotMinor = GetStorePackageVersionMajorDotMinor(); // Regenerate
            if (String.IsNullOrEmpty(PingString))
                PingString = GetPingString(); // Regenerate
            DelayedMessageToUserOnStartup = (string)SuspensionManager.SessionState["DelayedMessageToUserOnStartup"];
            // Probably don't need, since this is now in UserAndVersions: App.pd.plToken = (string)SuspensionManager.SessionState["TokenPL"];

            // Globals of type bool:
            ReportAltered = (bool)SuspensionManager.SessionState["ReportAltered"]; // used by ViewEditReport
            ReportDiscarded = (bool)SuspensionManager.SessionState["ReportDiscared"]; // used by ViewEditReport
            OutboxCheckBoxCurrentEventOnly = (bool)SuspensionManager.SessionState["OutboxCheckBoxCurrentEventOnly"];
            OutboxCheckBoxMyOrgOnly = (bool)SuspensionManager.SessionState["OutboxCheckBoxMyOrgOnly"];
            AllStationsCheckBoxMyOrgOnly = (bool)SuspensionManager.SessionState["AllStationsCheckBoxMyOrgOnly"];
            BlockWebServices = (bool)SuspensionManager.SessionState["BlockWebServices"];
            // Probably not: goodWebServiceConnectivity = false; // Determined by pings.  Don't bother with stale data: (bool)SuspensionManager.SessionState["goodWebServiceConnectivity"];
            AppFinishedLaunching = (bool)SuspensionManager.SessionState["AppFinishedLaunching"];
            // replaced by next item: ProcessingAllStationsList = (bool)SuspensionManager.SessionState["ProcessingAllStationsList"];
            ReloadingAllStationsList = (bool)SuspensionManager.SessionState["ReloadingAllStationsList"];

            // Complex types:
            // Most of restoration of these is handled in DoStartup, but we'll see what's needed here.
            // Some postings claim one can serialize complex types by decorating their classes & members as data contracts.  That was tried, but still some problems.
            // Instead, try JSON serialization to/from string suggested by http://stackoverflow.com/questions/18859089/windows-8-c-xaml-suspensionmanager-failed

            // Probably not: dispatcher = (CoreDispatcher)SuspensionManager.SessionState["dispatcher"];
            // Probably not: CurrentDisasterListForCombo = (ObservableCollection<TP_EventsDataItem>)SuspensionManager.SessionState["CurrentDisasterListForCombo"];
            // Probably not: CurrentDisaster = (TP_EventsDataItem)SuspensionManager.SessionState["CurrentDisaster"];
//PROBLEM FOR STORE APP CERT?:
//FIRST TRY            CurrentPatient = (TP_PatientReport)SuspensionManager.SessionState["CurrentPatient"]; // added April 28, 2014.  Current Patient has uncompleted New Report, might be swapped out when taking photo
            string state = (string)SuspensionManager.SessionState["CurrentPatient"]; // added April 28, 2014.  Current Patient has uncompleted New Report, might be swapped out when taking photo
            CurrentPatient = JsonConvert.DeserializeObject<TP_PatientReport>(state); // should we use DeserializeObjectAsync here?
            // Probably not: CurrentOtherSettings = (TP_OtherSettings)SuspensionManager.SessionState["CurrentOtherSettings"];
            // Probably not: ViewedDisaster = (TP_EventsDataItem)SuspensionManager.SessionState["ViewedDisaster"];  // used by ViewEditReport
            // Probably not: CurrentFilterProfile = (TP_FilterProfile)SuspensionManager.SessionState["CurrentFilterProfile"];
//PROBLEM FOR STORE APP CERT?:
//FIRST TRY            PatientDataGroups = (TP_PatientDataGroups)SuspensionManager.SessionState["PatientDataGroups"];
//UNNECESSARY AND UNHELPFUL, DoStartup's PatientDataGroups.Init, Init2 covers this:
//            state = (string)SuspensionManager.SessionState["PatientDataGroups"];
//            PatientDataGroups = JsonConvert.DeserializeObject<TP_PatientDataGroups>(state);
            // Probably not: SortFlyoutItem = (SortByItem)SuspensionManager.SessionState["SortFlyoutItem"];
            // Probably not: OrgPolicy = (TP_OrgPolicy)SuspensionManager.SessionState["OrgPolicy"]; // first entry on OrgPolicyList
            // Probably not: CurrentOrgContactInfo = (TP_OrgContactInfo)SuspensionManager.SessionState["CurrentOrgContactInfo"]; // first entry on OrgContactInfoList
            // Probably not: pl = (PLWS.plusWebServicesPortTypeClient)SuspensionManager.SessionState["pl"];
            // Probably not: service = (LPF_JSON)SuspensionManager.SessionState["service"];
            // Probably not: ErrorLog = (TP_ErrorLog)SuspensionManager.SessionState["ErrorLog"];
            // Probably not: pd = (ProtectData)SuspensionManager.SessionState["pd"];
            // Probably not: sendQueue = (TP_SendQueue)SuspensionManager.SessionState["sendQueue"];
        }
 private async void Webcam_Click(object sender, RoutedEventArgs e)
 {
     await SaveReportFieldsToObject(App.CurrentPatient, "");
     pr = App.CurrentPatient; // Probably not necessary since pr will be coing out of scope, but just in case.
     this.Frame.Navigate(typeof(WebcamPage), e);
 }