using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AyaNovaQBI
{
    /*
     TODO:
    
     
     */
    public partial class Map : Form
    {
        private AyaType _Type = AyaType.Customer;
        private DataTable _aya;
        private DataTable _qb;
        private viewtypes _currentView = viewtypes.All;

        private enum viewtypes
        {
            All,
            Unlinked,
            Linked
        }

        public Map()
        {
            InitializeComponent();
            Icon = AyaNovaQBI.Properties.Resources.logo;

            _aya = new DataTable("AyaNova");
            _aya.Columns.Add("name", typeof(string));
            _aya.Columns.Add("id", typeof(long));
            _aya.Columns.Add("linked", typeof(string));

            //Case 339
            _aya.DefaultView.Sort = "name asc";
            gridAya.DataSource = _aya;

            _qb = new DataTable("QuickBooks");
            _qb.Columns.Add("name", typeof(string));
            _qb.Columns.Add("id", typeof(string));
            _qb.Columns.Add("linked", typeof(bool));

            //Case 339
            _qb.DefaultView.Sort = "name asc";
            gridQB.DataSource = _qb;
        }

        private void Map_Load(object sender, EventArgs e)
        {
            Initialize();
            gridAya.ClearSelection();
            gridQB.ClearSelection();
            this.Text = "Customers";
            lblQuickBooksGridTitle.Text = "QuickBooks - Customers";
            lblAyaNovaGridTitle.Text = "AyaNova - Customers";
        }

        #region EXPORT
        private async void exportSelectedItemsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            bool IsAyaGrid = false;
            if (gridAya.SelectedRows.Count == 0 && gridQB.SelectedRows.Count == 0) return;

            IsAyaGrid = gridAya.SelectedRows.Count > 0;
            Waiting w = null;
            try
            {
                if (IsAyaGrid)
                {
                    if (MessageBox.Show(
                                "Export and link the selected AyaNova objects into QuickBooks.\r\n\r\n" +
                                "Are you sure?", "Export AyaNova objects", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
                                == DialogResult.No) return;
                    await ExportToQuickBooks();

                    w = new Waiting();
                    w.Show();
                    w.Ops = $"Export completed";
                    switch (_Type)
                    {
                        case AyaType.Customer:
                            w.Step = "Refreshing QB Customers cache";
                            await util.PopulateQBClientCacheAsync();
                            break;
                        case AyaType.Vendor:
                            w.Step = "Refreshing QB Vendors cache";
                            await util.PopulateQBVendorCacheAsync();
                            break;
                        case AyaType.ServiceRate:
                        case AyaType.TravelRate:
                        case AyaType.Part:
                            w.Step = "Refreshing QB Items cache";
                            await util.PopulateQBItemCacheAsync();
                            break;
                    }

                }
                else
                {
                    if (MessageBox.Show(
                                "Export and link the selected QuickBooks objects into AyaNova.\r\n\r\n" +
                                "Are you sure?", "Export QuickBooks objects", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
                                == DialogResult.No) return;
                    await ExportToAyaNova();
                    w = new Waiting();
                    w.Show();
                    w.Ops = $"Export completed";
                    switch (_Type)
                    {

                        case AyaType.Customer:
                            w.Step = "Refreshing AyaNova Customers cache";
                            await util.PopulateAyaClientList();
                            break;
                        case AyaType.Vendor:
                            w.Step = "Refreshing AyaNova Vendors cache";
                            await util.PopulateAyaVendorList();
                            break;
                        case AyaType.ServiceRate:
                            w.Step = "Refreshing AyaNova Service rates cache";
                            await util.PopulateAyaServiceRateList();
                            break;
                        case AyaType.TravelRate:
                            w.Step = "Refreshing AyaNova Travel rates cache";
                            await util.PopulateAyaTravelRateList();
                            break;
                        case AyaType.Part:
                            w.Step = "Refreshing AyaNova Parts cache";
                            await util.PopulateAyaPartList();
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                if (w != null)
                    w.Visible = false;
                await util.CrackDisplayAndIntegrationLogException(ex, "QBI:Map:ExportSelectedItems");
            }
            finally
            {
                if (w != null)
                    w.Close();
                menuStrip1.Enabled = gridQB.Enabled = gridAya.Enabled = true;
            }
            Initialize();
        }

        #region Export to AyaNova

        private async Task ExportToAyaNova()
        {
            this.Refresh();
            Cursor.Current = Cursors.WaitCursor;
            ArrayList alErrors = new ArrayList();
            Waiting w = new Waiting();
            w.Show();
            w.Ops = "Exporting from QuickBooks...";
            try
            {
                menuStrip1.Enabled = gridQB.Enabled = gridAya.Enabled = false;
                foreach (DataGridViewRow r in gridQB.SelectedRows)
                {
                    var QBItemName = r.Cells[0].Value.ToString();
                    var QBItemId = r.Cells[1].Value.ToString();
                    w.Step = QBItemName;

                    switch (_Type)
                    {
                        case AyaType.Customer:
                            await util.ImportQBCustomer(QBItemId, alErrors);
                            break;
                        case AyaType.Vendor:
                            await util.ImportQBVendor(QBItemId, alErrors);
                            break;

                        case AyaType.ServiceRate:
                            await util.ImportQBServiceRate(QBItemId, alErrors);
                            break;

                        case AyaType.TravelRate:
                            await util.ImportQBTravelRate(QBItemId, alErrors);
                            break;
                        case AyaType.Part:
                            await util.ImportQBPart(QBItemId, alErrors);
                            break;

                        default:
                            throw new System.NotSupportedException("ExportFromQuickBooks: NOT SUPPORTED type : " + _Type.ToString());
                    }
                }

                //display errors if any
                if (alErrors.Count != 0)
                {
                    w.Visible = false;

                    StringBuilder sb = new StringBuilder();
                    sb.Append("Export completed with some errors:\r\n\r\n");
                    foreach (object o in alErrors)
                    {
                        sb.Append((string)o);
                        sb.Append("\r\n************\r\n");

                    }

                    CopyableMessageBox cb = new CopyableMessageBox(sb.ToString());
                    cb.ShowDialog();
                }
            }
            catch (Exception ex)
            {
                w.Visible = false;
                await util.CrackDisplayAndIntegrationLogException(ex, "QBI:Map:ExportToAyaNova");
            }
            finally
            {
                w.Close();
                menuStrip1.Enabled = gridQB.Enabled = gridAya.Enabled = true;
            }

        }
        #endregion Export to AyaNova

        #region Export to QuickBooks

        private async Task ExportToQuickBooks()
        {
            Refresh();
            Cursor.Current = Cursors.WaitCursor;
            ArrayList alErrors = new ArrayList();
            Waiting w = new Waiting();
            w.Show();
            w.Ops = "Exporting from AyaNova...";
            try
            {
                bool firstPass = true;
                foreach (DataGridViewRow r in gridAya.SelectedRows)
                {
                    string AyaName = r.Cells[0].Value.ToString();
                    long AyaId = (long)r.Cells[1].Value;
                    w.Step = AyaName;
                    switch (_Type)
                    {
                        case AyaType.Customer:
                            await util.ImportAyaCustomer(AyaId, alErrors);
                            break;
                        case AyaType.Vendor:
                            await util.ImportAyaVendor(AyaId, alErrors);
                            break;
                        case AyaType.ServiceRate:
                            {
                                if (firstPass)
                                {
                                    SetQBImportServiceRateAccounts s = new SetQBImportServiceRateAccounts();
                                    if (s.ShowDialog() != DialogResult.OK)
                                    {
                                        s.Dispose();
                                        return;
                                    }
                                    s.Dispose();
                                    firstPass = false;
                                }
                                await util.ImportAyaServiceRate(AyaId, alErrors);
                            }
                            break;
                        case AyaType.TravelRate:
                            {
                                if (firstPass)
                                {
                                    SetQBImportServiceRateAccounts s = new SetQBImportServiceRateAccounts();
                                    if (s.ShowDialog() != DialogResult.OK)
                                    {
                                        s.Dispose();
                                        return;
                                    }
                                    s.Dispose();
                                    firstPass = false;
                                }
                                await util.ImportAyaTravelRate(AyaId, alErrors);
                            }
                            break;
                        case AyaType.Part:
                            {
                                if (firstPass)
                                {
                                    SetQBImportInventoryAccounts s = new SetQBImportInventoryAccounts();
                                    if (s.ShowDialog() != DialogResult.OK)
                                    {
                                        s.Dispose();
                                        return;
                                    }
                                    s.Dispose();
                                    firstPass = false;
                                }
                                await util.ImportAyaPart(AyaId, alErrors);
                            }
                            break;
                        default:
                            throw new System.NotSupportedException("ExportToQuickBooks: NOT SUPPORTED type: " + _Type.ToString());
                    }
                }

                await util.SaveIntegrationObject();

                //display errors if any
                if (alErrors.Count != 0)
                {
                    w.Visible = false;

                    StringBuilder sb = new StringBuilder();
                    sb.Append("Export completed with some errors:\r\n\r\n");
                    foreach (object o in alErrors)
                    {
                        sb.Append((string)o);
                        sb.Append("\r\n************\r\n");

                    }

                    CopyableMessageBox cb = new CopyableMessageBox(sb.ToString());
                    cb.ShowDialog();
                    cb.Dispose();

                }
            }
            catch (Exception ex)
            {

                await util.CrackDisplayAndIntegrationLogException(ex, "QBI:Map:ExportToQuickBooks");
            }
            finally
            {

                w.Close();
            }
        }
        #endregion exporttoqb


        #endregion export

        #region AUTOMATIC LINK
        private async void autoLinkToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //Loop through the current AyaNova list
            //foreach unlinked item 
            //	loop through the qb current list and if any names match then
            //	Link the two

            bool SaveIntegration = false;

            Waiting w = new Waiting();
            w.Show();
            w.Ops = "Autolinking matching items...";
            try
            {

                switch (_Type)
                {

                    case AyaType.Customer:
                        foreach (var i in util.AyaClientList)
                        {
                            if (i.Active)
                            {
                                IntegrationItem m = util.QBIntegration.Items.FirstOrDefault(z => z.ObjectId == i.Id && z.AType == _Type);
                                if (m == null)
                                {
                                    foreach (DataRow dr in util.QBClients.Rows)
                                    {
                                        if (i.Name == dr["FullName"].ToString())
                                        {
                                            w.Step = i.Name;
                                            m = new IntegrationItem { AType = _Type, IntegrationItemName = i.Name, IntegrationItemId = dr["ID"].ToString(), LastSync = System.DateTime.Now, ObjectId = i.Id };
                                            util.QBIntegration.Items.Add(m);
                                            SaveIntegration = true;
                                        }
                                    }
                                }
                            }
                        }
                        break;
                    case AyaType.Vendor:
                        foreach (var i in util.AyaVendorList)
                        {
                            if (i.Active)
                            {
                                IntegrationItem m = util.QBIntegration.Items.FirstOrDefault(z => z.ObjectId == i.Id && z.AType == _Type);
                                if (m == null)
                                {
                                    foreach (DataRow dr in util.QBVendors.Rows)
                                    {
                                        if (i.Name == dr["FullName"].ToString())
                                        {
                                            w.Step = i.Name;
                                            m = new IntegrationItem { AType = _Type, IntegrationItemName = i.Name, IntegrationItemId = dr["ID"].ToString(), LastSync = System.DateTime.Now, ObjectId = i.Id };
                                            util.QBIntegration.Items.Add(m);
                                            SaveIntegration = true;
                                        }
                                    }
                                }
                            }
                        }
                        break;
                    case AyaType.ServiceRate:
                        foreach (var i in util.AyaServiceRateList)
                        {
                            if (i.Active)
                            {
                                IntegrationItem m = util.QBIntegration.Items.FirstOrDefault(z => z.ObjectId == i.Id && z.AType == _Type);
                                if (m == null)
                                {
                                    foreach (DataRow dr in util.QBItems.Rows)
                                    {
                                        if (i.Name == dr["FullName"].ToString())
                                        {
                                            w.Step = i.Name;
                                            m = new IntegrationItem { AType = _Type, IntegrationItemName = i.Name, IntegrationItemId = dr["ID"].ToString(), LastSync = System.DateTime.Now, ObjectId = i.Id };
                                            util.QBIntegration.Items.Add(m);
                                            SaveIntegration = true;
                                        }
                                    }
                                }
                            }
                        }
                        break;
                    case AyaType.TravelRate:
                        foreach (var i in util.AyaServiceRateList)
                        {
                            if (i.Active)
                            {
                                IntegrationItem m = util.QBIntegration.Items.FirstOrDefault(z => z.ObjectId == i.Id && z.AType == _Type);
                                if (m == null)
                                {
                                    foreach (DataRow dr in util.QBItems.Rows)
                                    {
                                        if (i.Name == dr["FullName"].ToString())
                                        {
                                            w.Step = i.Name;
                                            m = new IntegrationItem { AType = _Type, IntegrationItemName = i.Name, IntegrationItemId = dr["ID"].ToString(), LastSync = System.DateTime.Now, ObjectId = i.Id };
                                            util.QBIntegration.Items.Add(m);
                                            SaveIntegration = true;
                                        }
                                    }
                                }
                            }
                        }
                        break;
                    case AyaType.Part:
                        foreach (var i in util.AyaPartList)
                        {
                            if (i.Active)
                            {
                                IntegrationItem m = util.QBIntegration.Items.FirstOrDefault(z => z.ObjectId == i.Id && z.AType == _Type);
                                if (m == null)
                                {
                                    foreach (DataRow dr in util.QBItems.Rows)
                                    {
                                        if (i.Name == dr["FullName"].ToString())
                                        {
                                            w.Step = i.Name;
                                            m = new IntegrationItem { AType = _Type, IntegrationItemName = i.Name, IntegrationItemId = dr["ID"].ToString(), LastSync = System.DateTime.Now, ObjectId = i.Id };
                                            util.QBIntegration.Items.Add(m);
                                            SaveIntegration = true;
                                        }
                                    }
                                }
                            }
                        }
                        break;

                }
                w.Visible = false;
                if (SaveIntegration)
                {
                    await util.SaveIntegrationObject();
                    Initialize();
                }
            }
            catch (Exception ex)
            {
                w.Visible = false;
                await util.CrackDisplayAndIntegrationLogException(ex, "QBI:Map:AutoLink");//case 3717
            }
            finally
            {
                w.Close();
            }
        }

        #endregion auto link

        #region LINK MANUALLY

        private async void linkSelectedItemsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            bool IsAyaGrid = false;
            if (gridAya.SelectedRows.Count == 0 && gridQB.SelectedRows.Count == 0) return;

            IsAyaGrid = gridAya.SelectedRows.Count > 0;
            bool SaveIntegration = false;

            if (IsAyaGrid)
            {
                #region AyaGrid
                //we have selection now get qb item
                MapSelectQBItem s = new MapSelectQBItem();

                s.QBItems = _qb;

                if (s.ShowDialog() == DialogResult.Cancel)
                    return;

                var QBItemName = s.SelectedQBItemName;
                var QBItemId = s.SelectedQBItemId;
                s.Dispose();
                var selectedAyaNovaIds = new List<long>();
                StringBuilder selectedAyaNovaNames = new StringBuilder();

                foreach (DataGridViewRow r in gridAya.SelectedRows)
                {
                    selectedAyaNovaNames.AppendLine(r.Cells[0].Value.ToString());
                    selectedAyaNovaIds.Add((long)r.Cells[1].Value);
                }


                //#################################
                //LINKING

                LinkAyaObjectToQBConfirm d = new LinkAyaObjectToQBConfirm();
                d.QBItem = QBItemName;
                d.AyaItems = selectedAyaNovaNames.ToString();
                if (d.ShowDialog() != DialogResult.OK)
                    return;


                ////ok, link away...
                foreach (DataGridViewRow r in gridAya.SelectedRows)
                {
                    string AyaName = r.Cells[0].Value.ToString();
                    long AyaId = (long)r.Cells[1].Value;



                    //Is AyaNova object already mapped?
                    IntegrationItem m = util.QBIntegration.Items.FirstOrDefault(z => z.ObjectId == AyaId && z.AType == _Type);
                    if (m != null)
                    {
                        //Is it already linked to the selected qb object?

                        //Yes so do nothing and continue on to the next object
                        if (m.IntegrationItemId == QBItemId)
                            continue;
                        else
                        {

                            //No, AyaNova object was mapped elsewhere, prompt user if this is ok
                            if (MessageBox.Show(
                                $"AyaNova object: {AyaName}\r\nIs already linked to QuickBooks object: {m.IntegrationItemName}\r\nDo you really want to change the link to the QuickBooks object: {QBItemName}\r\n",
                                "Change link?", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
                                == DialogResult.No) continue;

                        }

                        //If we're here it's because the object is already mapped
                        //but the users has signified they want to change the map to another object so...
                        if (!string.IsNullOrEmpty(QBItemId))//confirm not a removal
                        {
                            m.IntegrationItemId = QBItemId;
                            m.IntegrationItemName = QBItemName;
                            m.LastSync = System.DateTime.Now;
                            SaveIntegration = true;
                        }
                        else
                        {
                            //user is removing mapping so remove the integrationitem entirely from the collection
                            var didremove = util.QBIntegration.Items.Remove(m);
                            SaveIntegration = true;
                        }

                    }
                    else
                    {
                        if (!string.IsNullOrEmpty(QBItemId))//confirm not a removal
                        {
                            //not already present, so add it, easy peasy...
                            m = new IntegrationItem { AType = _Type, IntegrationItemName = QBItemName, IntegrationItemId = QBItemId, LastSync = System.DateTime.Now, ObjectId = AyaId };
                            util.QBIntegration.Items.Add(m);
                            SaveIntegration = true;
                        }
                    }
                }



                #endregion AyaGrid
            }
            else
            {
                #region QB GRID
                //################ 
                //QB GRID
                //

                if (gridQB.SelectedRows.Count > 1)
                {
                    MessageBox.Show("You can not link more than one QuickBooks\r\n" +
                                "object to a single AyaNova object", "Not supported", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                var QBItemName = gridQB.SelectedRows[0].Cells[0].Value.ToString();
                var QBItemId = gridQB.SelectedRows[0].Cells[1].Value.ToString();

                MapSelectAyaNovaItem s = new MapSelectAyaNovaItem();
                s.Items = _aya;
                if (s.ShowDialog() == DialogResult.Cancel)
                    return;

                var AyaId = s.SelectedItemId;
                s.Dispose();

                //This way is a one to one mapping so only one iteration and two potential things to do, add or change link
                //Is it already present?
                IntegrationItem m = util.QBIntegration.Items.FirstOrDefault(z => z.ObjectId == AyaId && z.AType == _Type);
                if (m != null)
                {
                    m.IntegrationItemId = QBItemId;
                    m.IntegrationItemName = QBItemName;
                    m.LastSync = System.DateTime.Now;
                    SaveIntegration = true;
                }
                else
                {
                    //not already present, so add it
                    m = new IntegrationItem { AType = _Type, IntegrationItemName = QBItemName, IntegrationItemId = QBItemId, LastSync = System.DateTime.Now, ObjectId = AyaId };
                    util.QBIntegration.Items.Add(m);
                    SaveIntegration = true;
                }

                #endregion qb grid
            }

            if (SaveIntegration)
            {
                await util.SaveIntegrationObject();
                Initialize();
            }
        }
        #endregion link manually

        #region UPDATE
        private async void updateSelectedItemsToolStripMenuItem_Click(object sender, EventArgs e)
        {

            if (gridAya.SelectedRows.Count == 0 && gridQB.SelectedRows.Count == 0) return;
            bool IsAyaGrid = false;
            IsAyaGrid = gridAya.SelectedRows.Count > 0;

            string sFrom = IsAyaGrid ? "QuickBooks" : "AyaNova";
            string sTo = IsAyaGrid ? "AyaNova" : "QuickBooks";

            MapApproveUpdateSelectedItems s = new MapApproveUpdateSelectedItems();

            string sType = "";
            switch (_Type)
            {

                case AyaType.Customer:
                    sType = "Customers";
                    break;
                case AyaType.Vendor:
                    sType = "Vendors";
                    break;
                case AyaType.Part:
                    sType = "Parts";
                    s.ShowUpdatePriceCostOnlyCheckBox = true;
                    break;
            }

            s.UpdateMessage = $"Update selected {sTo} {sType} from {sFrom} ";

            if (s.ShowDialog() == DialogResult.Cancel)
                return;

            bool PricesOnly = s.PriceOnly;
            s.Dispose();


            Waiting w = new Waiting();
            w.Show();
            w.Ops = $"Updating {sTo} {sType} from {sFrom}...";
            try
            {
                menuStrip1.Enabled = gridQB.Enabled = gridAya.Enabled = false;

                bool SaveIntegration = false;

                if (IsAyaGrid)
                {
                    #region AyaGrid so UPDATE AYANOVA FROM QB
                    switch (_Type)
                    {

                        case AyaType.Customer:
                            await util.PopulateQBClientCacheAsync();
                            break;
                        case AyaType.Vendor:
                            await util.PopulateQBVendorCacheAsync();
                            break;
                        case AyaType.Part:
                            await util.PopulateQBItemCacheAsync();
                            break;
                    }

                    foreach (DataGridViewRow r in gridAya.SelectedRows)
                    {
                        string AyaName = r.Cells[0].Value.ToString();
                        long AyaId = (long)r.Cells[1].Value;


                        //only linked items can be updated
                        IntegrationItem im = util.QBIntegration.Items.FirstOrDefault(z => z.ObjectId == AyaId && z.AType == _Type);
                        if (im != null)
                        {
                            w.Step = AyaName;
                            switch (_Type)
                            {
                                case AyaType.Customer:
                                    await util.RefreshAyaNovaCustomerFromQBAsync(im);
                                    break;
                                case AyaType.Vendor:
                                    await util.RefreshAyaNovaVendorFromQBAsync(im);
                                    break;
                                case AyaType.Part:
                                    await util.RefreshAyaNovaPartFromQBAsync(im, PricesOnly);
                                    break;
                            }
                            SaveIntegration = true;
                        }
                    }
                    switch (_Type)
                    {

                        case AyaType.Customer:
                            w.Step = "Refreshing AyaNova Customers cache";
                            await util.PopulateAyaClientList();
                            break;
                        case AyaType.Vendor:
                            w.Step = "Refreshing AyaNova Vendors cache";
                            await util.PopulateAyaVendorList();
                            break;
                        case AyaType.Part:
                            w.Step = "Refreshing AyaNova Parts cache";
                            await util.PopulateAyaPartList();
                            break;
                    }

                    #endregion AyaGrid
                }
                else
                {
                    #region QB GRID     

                    foreach (DataGridViewRow r in gridQB.SelectedRows)
                    {
                        var QBItemName = r.Cells[0].Value.ToString();
                        var QBItemId = r.Cells[1].Value.ToString();


                        //only linked items can be updated
                        IntegrationItem im = util.QBIntegration.Items.FirstOrDefault(z => z.IntegrationItemId == QBItemId && z.AType == _Type);
                        if (im != null)
                        {
                            w.Step = QBItemName;
                            switch (_Type)
                            {

                                case AyaType.Customer:
                                    await util.RefreshQBCustomerFromAyaNovaAsync(im);
                                    break;
                                case AyaType.Vendor:
                                    await util.RefreshQBVendorFromAyaNovaAsync(im);
                                    break;
                                case AyaType.Part:
                                    await util.RefreshQBPartFromAyaNova(im, PricesOnly);
                                    break;
                            }
                            SaveIntegration = true;
                        }
                    }


                    switch (_Type)
                    {
                        case AyaType.Customer:
                            w.Step = "Refreshing QB Customers cache";
                            await util.PopulateQBClientCacheAsync();
                            break;
                        case AyaType.Vendor:
                            w.Step = "Refreshing QB Vendors cache";
                            await util.PopulateQBVendorCacheAsync();
                            break;
                        case AyaType.ServiceRate:
                        case AyaType.TravelRate:
                        case AyaType.Part:
                            w.Step = "Refreshing QB Items cache";
                            await util.PopulateQBItemCacheAsync();
                            break;
                    }

                    #endregion qb grid
                }

                if (SaveIntegration)
                {
                    await util.SaveIntegrationObject();
                    Initialize();
                }
            }
            catch (Exception ex)
            {
                w.Visible = false;
                await util.CrackDisplayAndIntegrationLogException(ex, "QBI:Map:UpdateSelectedItems");
            }
            finally
            {
                w.Close();
                menuStrip1.Enabled = gridQB.Enabled = gridAya.Enabled = true;
            }



        }//eof
        #endregion update

        #region Initialize stuff
        /// <summary>
        /// Determine if row should be added to grid or now
        /// based on current view preferences and if item is already 
        /// linked or not
        /// </summary>
        /// <param name="bLinked"></param>
        /// <returns></returns>
        private bool DisplayRow(bool bLinked)
        {
            switch (_currentView)
            {
                case viewtypes.All:
                    return true;

                case viewtypes.Linked:
                    return bLinked;

                case viewtypes.Unlinked:
                    return !bLinked;


            }
            return true;
        }


        private void Initialize()
        {

            //clear both lists
            _aya.Rows.Clear();
            _qb.Rows.Clear();

            updateSelectedItemsToolStripMenuItem.Visible = false;

            switch (_Type)
            {

                case AyaType.Customer:
                    #region client
                    updateSelectedItemsToolStripMenuItem.Visible = true;

                    foreach (var i in util.AyaClientList)
                    {
                        if (i.Active)
                        {
                            var v = util.QBIntegration.Items.FirstOrDefault(z => z.AType == _Type && z.ObjectId == i.Id);
                            if (DisplayRow(v != null))
                                _aya.Rows.Add(new object[] { i.Name, i.Id, v == null ? null : v.IntegrationItemName });
                        }
                    }

                    //Fill QB table
                    foreach (DataRow dr in util.QBClients.Rows)
                    {
                        bool bLinked = util.QBIntegration.Items.Any(z => z.AType == _Type && z.IntegrationItemId == dr["ID"].ToString());
                        if (DisplayRow(bLinked))
                            _qb.Rows.Add(new object[] { dr["FullName"].ToString(), dr["ID"].ToString(), bLinked });
                    }
                    #endregion client
                    break;
                case AyaType.Vendor:
                    #region Vendor
                    updateSelectedItemsToolStripMenuItem.Visible = true;

                    foreach (var i in util.AyaVendorList)
                    {
                        if (i.Active)
                        {
                            var v = util.QBIntegration.Items.FirstOrDefault(z => z.AType == _Type && z.ObjectId == i.Id);
                            if (DisplayRow(v != null))
                                _aya.Rows.Add(new object[] { i.Name, i.Id, v == null ? null : v.IntegrationItemName });
                        }
                    }

                    //Fill QB table 
                    foreach (DataRow dr in util.QBVendors.Rows)
                    {
                        bool bLinked = util.QBIntegration.Items.Any(z => z.AType == _Type && z.IntegrationItemId == dr["ID"].ToString());
                        if (DisplayRow(bLinked))
                            _qb.Rows.Add(new object[] { dr["FullName"].ToString(), dr["ID"].ToString(), bLinked });
                    }
                    #endregion Vendor
                    break;
                case AyaType.ServiceRate:
                    #region Service rates
                    //_MostLikelyRateUnitChargeDescriptionID = 0;


                    foreach (var i in util.AyaServiceRateList)
                    {
                        if (i.Active)
                        {
                            var v = util.QBIntegration.Items.FirstOrDefault(z => z.AType == _Type && z.ObjectId == i.Id);
                            if (DisplayRow(v != null))
                                _aya.Rows.Add(new object[] { i.Name, i.Id, v == null ? null : v.IntegrationItemName });

                        }
                    }

                    //Fill QB table with QB items from prefetched table
                    foreach (DataRow dr in util.QBItems.Rows)
                    {
                        if ((util.qbitemtype)dr["Type"] == util.qbitemtype.Service || (util.qbitemtype)dr["Type"] == util.qbitemtype.OtherCharge)
                        {
                            bool bLinked = util.QBIntegration.Items.Any(z => z.AType == _Type && z.IntegrationItemId == dr["ID"].ToString());
                            if (DisplayRow(bLinked))
                                _qb.Rows.Add(new object[] { dr["FullName"].ToString(), dr["ID"].ToString(), bLinked });
                        }
                    }
                    #endregion Rate
                    break;

                case AyaType.TravelRate:
                    #region TravelRate rates
                    //_MostLikelyRateUnitChargeDescriptionID = 0;


                    foreach (var i in util.AyaTravelRateList)
                    {
                        if (i.Active)
                        {
                            var v = util.QBIntegration.Items.FirstOrDefault(z => z.AType == _Type && z.ObjectId == i.Id);
                            if (DisplayRow(v != null))
                                _aya.Rows.Add(new object[] { i.Name, i.Id, v == null ? null : v.IntegrationItemName });
                        }
                    }

                    //Fill QB table with QB items from prefetched table
                    foreach (DataRow dr in util.QBItems.Rows)
                    {
                        if ((util.qbitemtype)dr["Type"] == util.qbitemtype.Service || (util.qbitemtype)dr["Type"] == util.qbitemtype.OtherCharge)
                        {
                            bool bLinked = util.QBIntegration.Items.Any(z => z.AType == _Type && z.IntegrationItemId == dr["ID"].ToString());
                            if (DisplayRow(bLinked))
                                _qb.Rows.Add(new object[] { dr["FullName"].ToString(), dr["ID"].ToString(), bLinked });
                        }
                    }
                    #endregion Rate
                    break;

                case AyaType.Part:
                    #region Service parts                  
                    updateSelectedItemsToolStripMenuItem.Visible = true;

                    foreach (var i in util.AyaPartList)
                    {
                        if (i.Active)
                        {
                            var v = util.QBIntegration.Items.FirstOrDefault(z => z.AType == _Type && z.ObjectId == i.Id);
                            if (DisplayRow(v != null))
                                _aya.Rows.Add(new object[] { i.Name, i.Id, v == null ? null : v.IntegrationItemName });
                        }
                    }

                    //Fill QB table with QB items from prefetched table
                    foreach (DataRow dr in util.QBItems.Rows)
                    {
                        if ((util.qbitemtype)dr["Type"] == util.qbitemtype.Inventory || (util.qbitemtype)dr["Type"] == util.qbitemtype.NonInventory || (util.qbitemtype)dr["Type"] == util.qbitemtype.Assembly)
                        {
                            bool bLinked = util.QBIntegration.Items.Any(z => z.AType == _Type && z.IntegrationItemId == dr["ID"].ToString());
                            if (DisplayRow(bLinked))
                                _qb.Rows.Add(new object[] { dr["FullName"].ToString(), dr["ID"].ToString(), bLinked });
                        }
                    }
                    #endregion Part
                    break;

            }


        }


        #endregion init

        #region utility stuff

        private void showSubItemToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Set the current clicked item to item
            ToolStripMenuItem item = sender as ToolStripMenuItem;
            // Loop through all items in the subMenu and uncheck them but do check the clicked item
            foreach (ToolStripMenuItem tempItemp in showToolStripMenuItem.DropDownItems)
            {
                if (tempItemp == item)
                    tempItemp.Checked = true;
                else
                    tempItemp.Checked = false;
            }
            switch (item.Tag.ToString())
            {
                case "all":
                    {
                        if (_currentView != viewtypes.All)
                        {
                            _currentView = viewtypes.All;
                            Initialize();
                        }

                    }
                    break;
                case "linked":
                    {
                        if (_currentView != viewtypes.Linked)
                        {
                            _currentView = viewtypes.Linked;
                            Initialize();
                        }

                    }
                    break;
                case "unlinked":
                    {
                        if (_currentView != viewtypes.Unlinked)
                        {
                            _currentView = viewtypes.Unlinked;
                            Initialize();
                        }

                    }
                    break;

            }
        }





        private void customersToolStripMenuItem_Click(object sender, EventArgs e)
        {
            handleCheckOfObjectTypeMenuItem(sender, e);
            if (_Type == AyaType.Customer) return;
            _Type = AyaType.Customer;
            this.Text = "Customers";
            lblQuickBooksGridTitle.Text = "QuickBooks - Customers";
            lblAyaNovaGridTitle.Text = "AyaNova - Customers";
            updateSelectedItemsToolStripMenuItem.Visible = true;
            Initialize();
        }

        private void serviceRatesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            handleCheckOfObjectTypeMenuItem(sender, e);
            if (_Type == AyaType.ServiceRate) return;
            _Type = AyaType.ServiceRate;
            this.Text = "Service rates";
            lblQuickBooksGridTitle.Text = "QuickBooks - Service / Other items";
            lblAyaNovaGridTitle.Text = "AyaNova - Service rates";
            updateSelectedItemsToolStripMenuItem.Visible = false;
            Initialize();
        }

        private void travelRatesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            handleCheckOfObjectTypeMenuItem(sender, e);
            if (_Type == AyaType.TravelRate) return;
            _Type = AyaType.TravelRate;
            this.Text = "Travel rates";
            lblQuickBooksGridTitle.Text = "QuickBooks - Service / Other items";
            lblAyaNovaGridTitle.Text = "AyaNova - Travel rates";
            updateSelectedItemsToolStripMenuItem.Visible = false;
            Initialize();
        }

        private void partsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            handleCheckOfObjectTypeMenuItem(sender, e);
            if (_Type == AyaType.Part) return;
            _Type = AyaType.Part;
            this.Text = "Parts";
            lblQuickBooksGridTitle.Text = "QuickBooks - Inventory / non-inventory / assembly items";
            lblAyaNovaGridTitle.Text = "AyaNova - Parts";
            updateSelectedItemsToolStripMenuItem.Visible = true;
            Initialize();
            if (!util.QBIntegration.Items.Any(z => z.AType == AyaType.Vendor))
            {
                MessageBox.Show(
                "If you plan on importing QuickBooks items into AyaNova parts\r\n" +
                "we recommend you import or link QuickBooks vendors first.\r\n\r\n" +
                "This will ensure items in QuickBooks with a preferred vendor\r\n" +
                "are imported into AyaNova as parts with their Wholesaler field \r\n" +
                "set in AyaNova to a matching QuickBooks vendor",
                    "No QuickBooks vendors are linked");

            }
        }

        private void vendorsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            handleCheckOfObjectTypeMenuItem(sender, e);
            if (_Type == AyaType.Vendor) return;
            _Type = AyaType.Vendor;
            this.Text = "Vendors";
            lblQuickBooksGridTitle.Text = "QuickBooks - Vendors";
            lblAyaNovaGridTitle.Text = "AyaNova - Vendors";
            updateSelectedItemsToolStripMenuItem.Visible = true;
            Initialize();
        }


        private void handleCheckOfObjectTypeMenuItem(object sender, EventArgs e)
        {
            // Set the current clicked item to item
            ToolStripMenuItem item = sender as ToolStripMenuItem;
            // Loop through all items in the subMenu and uncheck them but do check the clicked item
            foreach (ToolStripMenuItem tempItemp in objectToolStripMenuItem.DropDownItems)
            {
                if (tempItemp == item)
                    tempItemp.Checked = true;
                else
                    tempItemp.Checked = false;
            }
        }




        private void gridQB_SelectionChanged(object sender, EventArgs e)
        {
            var hasSelection = gridQB.SelectedRows.Count > 0;

            if (hasSelection)
                gridAya.ClearSelection();
        }

        private void gridAya_SelectionChanged(object sender, EventArgs e)
        {
            var hasSelection = gridAya.SelectedRows.Count > 0;

            if (hasSelection)
                gridQB.ClearSelection();
        }







        #endregion utility stuff



    }//eoc
}//eons
