using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Forms.Integration; using TradeIdeas.XML; using System.Xml; using TradeIdeas.MiscSupport; using TradeIdeas.TIProData; using Label = System.Windows.Controls.Label; using System.Globalization; using static TradeIdeas.TIProGUI.EnhancedSingleStockWindow.TopListPanel; namespace TradeIdeas.TIProGUI.EnhancedSingleStockWindow { public class SimilarTab : TabItem, IMasterWindowResize { private WPF_SingleStock _mainWindow = null; private Grid _hostGrid = null; private WindowsFormsHost _host = new WindowsFormsHost(); private TopListPanel _tPanel = new TopListPanel(); private int startSymbolTally = 0; // tells us when we should ultimately give a server call within the Similar Tab go get data when we're in the Competitor mode private Grid _dataPanel; private StackPanel _pnlTopList; private Label _lblPriceSimilar; private Label _lblChangeDollarPercentSimilar; private Label _lblCompanyNameSimilar; private Label _lblTimeSimilar; private Label _lblDateSimilar; private string _timeString = ""; private const int SCROLL_BAR_OFFSET = 6; private const int DATA_PANEL_HEIGHT = 61; public SimilarTab() { } public void setStartSymbolTally(int startTally) { startSymbolTally = startTally; } public void setSingleStockWindowInstance(WPF_SingleStock instance) { _mainWindow = instance; _hostGrid = instance.hostGrid; _dataPanel = instance.dataPanel; _pnlTopList = instance.pnlTopList; //labels _lblPriceSimilar = instance.lblPriceSimilar; _lblChangeDollarPercentSimilar = instance.lblChangeDollarPercentSimilar; _lblCompanyNameSimilar = instance.lblCompanyNameSimilar; _lblTimeSimilar = instance.lblTimeSimilar; _lblDateSimilar = instance.lblDateSimilar; //set event handlers _mainWindow.formLoadedEvent += _MaininWindow_formLoadedEvent; _mainWindow.receiveTopListDataEvent += MainWindow_receiveTopListDataEvent; _mainWindow.subIndustryReceivedEvent += _mainWindow_subIndustryReceivedEvent; _mainWindow.onPriceActionDataReceived += _mainWindow_onPriceActionDataReceived; } private void MainWindow_receiveTopListDataEvent(TopListInfo metaData, RowData rowData, DateTime? start, DateTime? end, bool validDataReceived) { if (validDataReceived) { _lblDateSimilar.Visibility = Visibility.Visible; _lblTimeSimilar.Visibility = Visibility.Visible; getTimeString(start, end); processUserNonchangeables(rowData); } else { _lblDateSimilar.Visibility = Visibility.Hidden; _lblTimeSimilar.Visibility = Visibility.Hidden; } } private void getTimeString(DateTime? start = null, DateTime? end = null) { StringBuilder result = new StringBuilder(); string dateDetail = ""; _lblDateSimilar.Content = ""; // Not used anymore. if (null != end) result.Append(((DateTime)end).ToString(GuiEnvironment.AlertTimeShortFormat)); else if (null != start) result.Append(((DateTime)start).ToString(GuiEnvironment.AlertTimeShortFormat)); if ((null != start) || (null != end)) { DateTime date = end.HasValue ? end.Value : start.Value; try { string dateFormat = GuiEnvironment.XmlConfig.Node("DATE_FORMAT").PropertyForCulture("TEXT", "M/d/yyyy"); if (null != dateFormat) { if (null != end) { dateDetail = end.Value.ToString(dateFormat); } else if (null != start) { dateDetail = start.Value.ToString(dateFormat); } } else { dateDetail = ""; } } catch { // Presumaly a bad value in the file could lead us here. By default print nothing. } } // _timeString always include the month, date, and year. _timeString = result.ToString() + " " + dateDetail; } private void _mainWindow_onPriceActionDataReceived(Double ry, Double rv, Double fcp, Double r10D, Double r3mo, Double r6mo) { _tPanel.setPriceActionData( ry, rv,fcp, r10D, r3mo, r6mo); } private void _mainWindow_subIndustryReceivedEvent(string subIndustry,string industry,string industryGroup,string subSector,string sector) { string retVal; Sector info; if (subIndustry != "") { retVal = subIndustry; info = Sector.SUB_INDUSTRY; } else if (subIndustry == "" && industry != "") { retVal = industry; info = Sector.INDUSTRY; } else if (industry == "" && industryGroup != "") { retVal = industryGroup; info = Sector.INDUSTRY_GROUP; } else if (industryGroup == "" && subSector != "") { retVal = subSector; info = Sector.SUB_SECTOR; } else { retVal = sector; info = Sector.SECTOR; } _tPanel.setRawSectorDataStrings(sector.Trim(),subSector.Trim(), industryGroup.Trim(), industry.Trim(), subIndustry.Trim()); if (startSymbolTally == 1) _tPanel.onNewDataForCompetitorSymbol(retVal, info); } private void _MaininWindow_formLoadedEvent(double mainWindowWidth) { _host.Child = _tPanel; _pnlTopList.Children.Add(_host); _tPanel.beginToplist(); //on duplication, this is fired before "startTopList(); but both are needed so that the datagrid gets populated properly(all columns) } public void unLoadEventHandlers() { _mainWindow.formLoadedEvent -= _MaininWindow_formLoadedEvent; _mainWindow.receiveTopListDataEvent -= MainWindow_receiveTopListDataEvent; _mainWindow.subIndustryReceivedEvent -= _mainWindow_subIndustryReceivedEvent; _mainWindow.onPriceActionDataReceived -= _mainWindow_onPriceActionDataReceived; _tPanel.unLoadEventHandlers(); stopToplistData(); } public String getConfigString() { return _tPanel.getConfig(); } public void startTopList() // this is fired when the tab selection is changed to this tab(handler in WPF_SingleStock.xaml.cs { _tPanel.beginToplist();//weird that I need to call this again, if navigating for the first time here after a new single stock window has been created. } private void processUserNonchangeables(RowData rowData) //The "non-grid" items(i.e. stuff not configured from config window { _lblPriceSimilar.FontSize = 36; _lblPriceSimilar.Content = (DetailsTab.getDoubleString(rowData, "c_Price", 2) == "***") ? "" : DetailsTab.getDoubleString(rowData, "c_Price", 2); double test = DetailsTab.getTextLength(_lblPriceSimilar.Content.ToString(), _lblPriceSimilar); if (test > 141) { _lblPriceSimilar.FontSize = 24; _lblPriceSimilar.Margin = new Thickness(0, 10, 0, 0); } else { _lblPriceSimilar.FontSize = 36; _lblPriceSimilar.Margin = new Thickness(0, 0, 0, 0); } string exchangeName = rowData.GetExchange(); string symbl = _mainWindow.getCurrentSymbol(); string exchangeSymbolContent = "(" + exchangeName + ":" + symbl + ")"; _lblCompanyNameSimilar.Content = rowData.GetCompanyName() + " " + exchangeSymbolContent; _lblTimeSimilar.Content = _timeString; decimal changeDollar = 0; double changePercent = 0; if (rowData.Data.ContainsKey("c_FCP") && rowData.Data.ContainsKey("c_FCD") && ServerFormats.TryParse(rowData.GetAsString("c_FCP"), out changePercent) && Decimal.TryParse(rowData.GetAsString("c_FCD"), NumberStyles.Any | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out changeDollar)) { Brush textColor; string textPrefix = ""; if (changeDollar > 0) { textPrefix = "+ "; textColor = System.Windows.Media.Brushes.Green; } else if (changeDollar < 0) { textColor = Brushes.Red; } else { textColor = Brushes.Black; } string chgDollar = textPrefix + Math.Round(changeDollar, 2).ToString("#,0.00"); string chgPercent = " (" + Math.Round(changePercent, 2).ToString("0.00") + "%)"; _lblChangeDollarPercentSimilar.Content = chgDollar + chgPercent; _lblChangeDollarPercentSimilar.Foreground = textColor; } } private void clearLabelData() //set to "" when one enters invalid string. This method clears out *non-grid* data in the details tab, { _lblCompanyNameSimilar.Content = ""; _lblChangeDollarPercentSimilar.Content = ""; _lblPriceSimilar.Content = ""; } public void onMasterWindowResize(SizeChangedEventArgs e) { //In the designer, we have this set as Horizontal Alignment.Stretch. We then // change to HorizontalAlignment.Left in this code block. This is when we resize, it // ensures that the left side of the grid stays "anchored" to the window. If we kept it // at HorizontalAlignment.Stretch, we have an ever-increasing white gap between the grid and the //left edge of its container when the width is reduced. if (_hostGrid == null) return; _hostGrid.HorizontalAlignment = System.Windows.HorizontalAlignment.Left; Double newHeight = _hostGrid.Height - DATA_PANEL_HEIGHT; if (newHeight < 0) newHeight = 0; _pnlTopList.Height = newHeight; if ((int)e.NewSize.Width >= SCROLL_BAR_OFFSET) _hostGrid.Width = _host.Width = _tPanel.Width = (int)e.NewSize.Width - SCROLL_BAR_OFFSET; else _hostGrid.Width = _host.Width = _tPanel.Width = (int)e.NewSize.Width; } public void setCurrentSymbol(string symbol) { _tPanel.setCurrentSymbol(symbol); } public TopListPanel getTopListPanel() { return _tPanel; } public void setSymbolLinking(bool symbolLinkingEnabled) { _tPanel.setSymbolLinking(symbolLinkingEnabled); } public void setValidSymbolStatus(bool value) { _tPanel.setValidSymbolStatus(value); } public void setOutsideMarketHours(bool value) { _tPanel.setOutsideMarkeHours(value); } public bool getValidSymbolStatus() { return _tPanel.getValidSymbolStatus(); } public void stopToplistData() { _tPanel.stopTopListData(); } public void setViewModeOnRestore(TopListPanel.ViewMode vM) //for duplication/layoutPurposes { _tPanel.setViewModeOnRestore(vM); } public TopListPanel.ViewMode getViewMode() //for duplication/layoutPurposes { return _tPanel.getViewMode(); } public void clearData() //this is fired when invalid symbol is entered. { _tPanel.clearData(); clearLabelData(); } public void duplicate() { _tPanel.duplicate(); } public XmlNode saveGridColumnForDuplication(XmlNode description) { XmlNode retVal = _tPanel.saveGridColumnForDuplication(description); return retVal; } //The below getters/setters used a lot specifically for duplication process of the whole single stock window. We're //getting and setting values for the Toplist Panel. public void setPriceActionNode(XmlNode node) { _tPanel.setPriceActionNode(node); } public void setCompetitorNode(XmlNode node) { _tPanel.setCompetitorNode(node); } public String getSubindustryString() { return _tPanel.getSubindustryString(); } public void setSubindustryOnRestore(String s) { _tPanel.setSubindustryOnRestore(s); } public bool getLocalSortEnabled() { return _tPanel.getLocalSortEnabled(); } public void setLocalSortEnabled(bool value) { _tPanel.setLocalSortEnabled(value); } public String getLocalSortCode() { return _tPanel.getLocalSortCode(); } public void setLocalSortCode(string code) { _tPanel.setLocalSortCode(code); } public String getLocalSortType() { return _tPanel.getLocalSortType(); } public void setLocalSortType(TopListSortType t) { _tPanel.setLocalSortType(t); } public void updateColumnListStateOnLostFocus() { _tPanel.updateColumnListStateOnLostFocus(); } } }