/// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object can be used to retrieve data from input parameters and
        /// to store data in output parameters.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            //input variables
            string imgName   = "";
            var    viewNames = new List <string>();
            int    width     = 600;
            int    height    = 600;

            //get data
            DA.GetData(0, ref imgName);
            DA.GetDataList(1, viewNames);
            DA.GetData(2, ref width);
            DA.GetData(3, ref height);
            //defense
            if (width < 50 || height < 50)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Width and Height must be greater than 50 pixels.");
                return;
            }

            //set output
            var imageP = new ImgParam(imgName, viewNames, width, height);

            //var imageP = new Dictionary<string, object>();
            //imageP.Add("imgName", imgName);
            //imageP.Add("viewNames", viewNames);
            //imageP.Add("Width", width);
            //imageP.Add("Height", height);
            //DA.SetDataList(0, imageP);
            DA.SetData(0, imageP);
        }
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object can be used to retrieve data from input parameters and
        /// to store data in output parameters.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            bool writeFile = false;

            //input variables
            List <string> inputs  = new List <string>();
            List <string> outputs = new List <string>();

            List <object> inJSON = new List <object>();
            //object inJSON = null;

            var imgParams = new ImgParam();

            //get data
            DA.GetData(0, ref Folder);
            DA.GetDataList(1, inputs);
            DA.GetDataList(2, outputs);
            DA.GetData(3, ref imgParams);
            DA.GetDataList(4, inJSON);
            DA.GetData(5, ref writeFile);

            //operations is ExpandoObject
            inJSON.RemoveAll(item => item == null);
            var JSON = new threeDParam();

            if (!inJSON.IsNullOrEmpty())
            {
                JSON = new threeDParam(inJSON);
            }


            Dictionary <string, string> inputCSVstrings  = ColibriBase.FormatDataToCSVstring(inputs, "in:");
            Dictionary <string, string> outputCSVstrings = ColibriBase.FormatDataToCSVstring(outputs, "out:");
            //Dictionary<string, string> imgParamsClean = ColibriBase.ConvertBactToDictionary(imgParams);

            string csvPath = Folder + @"\data.csv";
            //var rawData = inputs;
            //int inDataLength = rawData.Count;
            //rawData.AddRange(outputs);
            //int allDataLength = rawData.Count;

            //Parsing data to csv format
            string flyID      = inputCSVstrings["FlyID"];
            string keyReady   = inputCSVstrings["DataTitle"];
            string valueReady = inputCSVstrings["DataValue"];

            //add output data when it is not empty
            keyReady   = string.IsNullOrWhiteSpace(outputCSVstrings["DataTitle"]) ? keyReady : keyReady + "," + outputCSVstrings["DataTitle"];
            valueReady = string.IsNullOrWhiteSpace(outputCSVstrings["DataValue"]) ? valueReady : valueReady + "," + outputCSVstrings["DataValue"];

            string systemSafeFileName = flyID.Replace(" ", "");

            systemSafeFileName = Path.GetInvalidFileNameChars()
                                 .Aggregate(systemSafeFileName, (current, c) => current.Replace(c.ToString(), ""));

            //write only when toggle is connected
            if (this.Params.Input.Last().Sources.Any())
            {
                //first open check
                if (_isFirstTimeOpen)
                {
                    _isFirstTimeOpen = false;
                    setWriteFileToFalse();
                    return;
                }
                this._write = writeFile;
            }
            else
            {
                this._write = false;
            }

            //var ViewNames = new List<string>();


            //if we aren't told to write, clean out the list of already written items
            if (!_write)
            {
                DA.SetDataList(0, _printOutStrings);
                _alreadyWrittenLines = new List <string>();
                this.Message         = "[OVERRIDE MODE]\n" + OverrideTypes.ToString() + "\n------------------------------\n[RECORDING DISABLED]\n";
                return;
            }

            //if we are told to run and we haven't written this line yet, do so

            if (_write)
            {
                //Check folder if existed
                checkStudyFolder(Folder);

                //check csv file
                if (!File.Exists(csvPath))
                {
                    //clean out the list of already written items
                    _printOutStrings = new List <string>();
                    //add key lines

                    //check if there is one or more imges
                    if (imgParams.IsDefined)
                    {
                        int imgCounts = imgParams.ViewNames.Count;
                        imgCounts = imgCounts > 0 ? imgCounts : 1;

                        if (imgCounts > 1)
                        {
                            for (int i = 1; i <= imgCounts; i++)
                            {
                                keyReady += ",img_" + i;
                            }
                        }
                        else
                        {
                            keyReady += ",img";
                        }
                    }
                    else
                    {
                        keyReady += ",img";
                    }

                    if (JSON.IsDefined)
                    {
                        keyReady += ",threeD";
                    }

                    keyReady += Environment.NewLine;
                    File.WriteAllText(csvPath, keyReady);
                    _alreadyWrittenLines.Add("[Title] " + keyReady);
                }
                else
                {
                    //add data lins
                    if (!_alreadyWrittenLines.Contains("[FlyID] " + flyID))
                    {
                        string writeInData = valueReady;

                        //save img
                        string imgFileName = captureViews(imgParams, systemSafeFileName);
                        writeInData += "," + imgFileName;

                        //save json
                        if (JSON.IsDefined)
                        {
                            string jsonFileName = systemSafeFileName + ".json";
                            string jsonFilePath = Folder + @"\" + jsonFileName;
                            File.WriteAllText(jsonFilePath, JSON.JsonSting);
                            writeInData += "," + jsonFileName;
                        }

                        //save csv // add data at the end
                        //writeInData = string.Format("{0},{1},{2}\n", valueReady, imgFileName, jsonFileName);
                        writeInData += "\n";
                        File.AppendAllText(csvPath, writeInData);

                        //add this line to our list of already written lines
                        _alreadyWrittenLines.Add("[FlyID] " + flyID);
                    }
                }

                _printOutStrings = _alreadyWrittenLines;

                //updateMsg();
                this.Message = "[OVERRIDE MODE]\n" + OverrideTypes.ToString() + "\n------------------------------\n[RECORDING STARTED]\n";
                DA.SetDataList(0, _printOutStrings);
            }

            //set output
            //DA.SetData(0, writeInData);
        }
        private string captureViews(ImgParam imgParams, string flyID)
        {
            if (imgParams.IsActive)
            {
                //string imgID = flyID;
                var ViewNames = new List <string>();
                int width     = 600;
                int height    = 600;


                string imgName = flyID;
                string imgPath = string.Empty;

                var imgCSV = new List <string>();


                // overwrite the image parameter setting if user has inputed the values
                if (imgParams.IsDefined)
                {
                    bool isThereNoImgName = imgParams.SaveName == "defaultName";
                    imgName   = isThereNoImgName ? imgName : imgParams.SaveName;
                    ViewNames = imgParams.ViewNames;
                    width     = imgParams.Width;
                    height    = imgParams.Height;
                }

                Size imageSize = new Size(width, height);
                //If ViewNames is empty, which means to capture current active view
                var activeView = Rhino.RhinoDoc.ActiveDoc.Views.ActiveView;
                if (!ViewNames.Any())
                {
                    imgName += ".png";
                    imgPath  = Folder + @"\" + imgName;

                    activeView.Redraw();

                    var pic = activeView.CaptureToBitmap(imageSize);
                    pic.Save(imgPath);

                    //return here, and skip the following views' check
                    return(imgName);
                }

                //If user set View Names
                var views      = Rhino.RhinoDoc.ActiveDoc.Views.ToDictionary(v => v.ActiveViewport.Name, v => v);
                var namedViews = Rhino.RhinoDoc.ActiveDoc.NamedViews.ToDictionary(v => v.Name, v => v);

                //string newImgPathWithViewName = ImagePath;
                string currentImgName = imgName;
                for (int i = 0; i < ViewNames.Count; i++)
                {
                    string viewName      = ViewNames[i];
                    string existViewName = string.Empty;

                    if (views.ContainsKey(viewName))
                    {
                        activeView    = views[viewName];
                        existViewName = viewName;
                    }
                    else if (namedViews.ContainsKey(viewName))
                    {
                        existViewName = viewName;
                        var namedViewIndex = Rhino.RhinoDoc.ActiveDoc.NamedViews.FindByName(viewName);
                        Rhino.RhinoDoc.ActiveDoc.NamedViews.Restore(namedViewIndex, Rhino.RhinoDoc.ActiveDoc.Views.ActiveView, true);
                    }

                    //capture
                    if (!string.IsNullOrEmpty(existViewName))
                    {
                        currentImgName = imgName + "_" + existViewName + ".png";
                        imgCSV.Add(currentImgName);
                        imgPath = Folder + @"\" + currentImgName;
                        //save imgs
                        activeView.Redraw();
                        var pic = activeView.CaptureToBitmap(imageSize);
                        pic.Save(imgPath);
                    }
                }

                return(string.Join(",", imgCSV));
            }
            else
            {
                return("");
            }
        }