public Form_Controller(Device device)
        {
            this.device = device;

            InitializeComponent();

            this.Text = "Controller settings (" + device.name + ")";

            int y = offset_corner + 30;

            Point label_loc_eventType = new Point(offset_x + offset_corner, y);

            foreach (string eventType in Enum.GetNames(typeof(Device.EventType)))
            {
                Label label = new Label();
                label.Text     = eventType;
                label.Location = label_loc_eventType;
                label.Size     = new Size(size_x, size_y);
                this.Controls.Add(label);

                label_loc_eventType.Offset(offset_x, 0);
            }

            //create checkboxs
            string[]          bodyPartNames = Enum.GetNames(typeof(Device.BodyPart));
            Device.BodyPart[] bodyPartIds   = (Device.BodyPart[])Enum.GetValues(typeof(Device.BodyPart));

            for (int i = 0; i < bodyPartNames.Length; i++)
            {
                String          bodyPart   = bodyPartNames[i];
                Device.BodyPart bodyPartId = bodyPartIds[i];

                y += offset_y;
                Point location = new Point(offset_corner, y);
                Label label    = new Label();
                label.Text     = bodyPart;
                label.Location = location;
                label.Size     = new Size(size_x, size_y);
                this.Controls.Add(label);

                Device.EventType[] eventTypeIds = (Device.EventType[])Enum.GetValues(typeof(Device.EventType));
                for (int j = 0; j < eventTypeIds.Length; j++)
                {
                    Device.EventType eventTypeId = eventTypeIds[j];


                    location.Offset(offset_x, 0);
                    CheckBox cb = new CheckBox();
                    cb.Location = location;
                    cb.Size     = new Size(size_x, size_y);
                    cb.Checked  = device.HasType(bodyPartId, eventTypeId);
                    this.Controls.Add(cb);

                    checkBox_list.Add(new CheckBox_custom(cb, bodyPartId, eventTypeId));
                }
            }
            numericUpDown_min.Value = (int)(device.MinPosition * 100.0d);
            numericUpDown_max.Value = (int)(device.MaxPosition * 100.0d);
        }
        private void Button1_Click(object sender, EventArgs e)
        {
            Device.devices.Clear();
            for (int i = 0; i < listBox_devices.Items.Count; i++)
            {
                if (listBox_devices.GetItemChecked(i))
                {
                    Device device = (Device)listBox_devices.Items[i];
                    Device.devices.Add(device);


                    //Load saved settings from Registery
                    string[]          bodyPartNames = Enum.GetNames(typeof(Device.BodyPart));
                    Device.BodyPart[] bodyPartIds   = (Device.BodyPart[])Enum.GetValues(typeof(Device.BodyPart));
                    for (int j = 0; j < bodyPartNames.Length; j++)
                    {
                        String          bodyPartName = bodyPartNames[j];
                        Device.BodyPart bodyPartId   = bodyPartIds[j];


                        string[]           eventTypeNames = Enum.GetNames(typeof(Device.EventType));
                        Device.EventType[] eventTypeIds   = (Device.EventType[])Enum.GetValues(typeof(Device.EventType));
                        for (int k = 0; k < eventTypeNames.Length; k++)
                        {
                            String           eventTypeName = eventTypeNames[k];
                            Device.EventType eventTypeId   = eventTypeIds[k];

                            RegistryKey keyEvent = Registry.CurrentUser.OpenSubKey(String.Format(@"SOFTWARE\Butthesda\Device Settings\{0}\{1}\{2}", device.name, bodyPartName, eventTypeName));

                            if (keyEvent != null && Convert.ToBoolean(keyEvent.GetValue("Checked")))
                            {
                                device.SetType(bodyPartId, eventTypeId, true);
                            }
                        }
                    }

                    RegistryKey key = Registry.CurrentUser.OpenSubKey(String.Format(@"SOFTWARE\Butthesda\Device Settings\{0}", device.name));
                    if (key != null)
                    {
                        int max = Convert.ToInt32(key.GetValue("Max"));
                        if (max == 0)
                        {
                            max = 100;
                        }
                        ;                            //default
                        int min = Convert.ToInt32(key.GetValue("Min"));

                        device.MinPosition = (double)min / 100.0d;
                        device.MaxPosition = (double)max / 100.0d;
                    }
                }
            }

            this.Close();
        }
        public BodyPart_Data(string bodyPart_dir, Device.BodyPart bodyPart)
        {
            this.bodyPart = bodyPart;

            string[] eventType_dirs = Directory.GetFiles(bodyPart_dir);
            foreach (string eventType_dir in eventType_dirs)
            {
                string s_eventType  = Path.GetFileName(eventType_dir).ToLower();
                bool   is_funscript = false;
                bool   is_estim     = false;
                if (s_eventType.EndsWith(".funscript"))
                {
                    is_funscript = true;
                    s_eventType  = s_eventType.Remove(s_eventType.Length - ".funscript".Length);
                }
                else if (s_eventType.EndsWith(".mp3"))
                {
                    is_estim    = true;
                    s_eventType = s_eventType.Remove(s_eventType.Length - ".mp3".Length);
                }
                else
                {
                    continue;
                }


                Device.EventType eventType;
                try
                {
                    eventType = (Device.EventType)Enum.Parse(typeof(Device.EventType), s_eventType, true);
                }
                catch
                {
                    continue;
                }

                int index = (int)eventType;

                if (eventTypes[index] == null)
                {
                    eventTypes[index] = new EventType_Data(eventType);
                }

                if (is_estim)
                {
                    eventTypes[index].Add_Estim(eventType_dir);
                }
                else if (is_funscript)
                {
                    eventTypes[index].Add_Funscript(eventType_dir);
                }
            }
        }
        private List <Running_Event> PlayEvent(Actor_Data event_data, bool synced_by_animation)
        {
            // Some events are meant for multiple body parts. If a physical device is mapped to more than one of these body parts AND
            // a single event triggers multiple body parts in one call of this method, only the first effect is played on a device.
            uint devicesReceivedEventAlready = 0;  // used as bitmask for Device.devices
            uint currentDeviceIndex;

            // These loops can create 0, 1 or more events on a device, e.g. if one device is registered for multiple body parts.
            // We return a list of all created events so we don't loose the reference to an event object,
            // because we need to be able to call the End() method to prematurely stop an event.

            List <Running_Event> runningEvents = new List <Running_Event>();

            foreach (BodyPart_Data bodypart in event_data.bodyparts)
            {
                if (bodypart == null)
                {
                    continue;
                }
                Device.BodyPart bodyPart_id = bodypart.bodyPart;  // Head, Body, Breast, ...

                foreach (EventType_Data eventType in bodypart.eventTypes)
                {
                    if (eventType == null)
                    {
                        continue;
                    }
                    Device.EventType eventType_id = eventType.eventType;  // Shock, Damage, Penetrate, Vibrate, Equip (with footsteps==Penetrate)

                    currentDeviceIndex = 1;
                    foreach (Device device in Device.devices)                                                                     // physical device
                    {
                        if (device.HasType(bodyPart_id, eventType_id) && (devicesReceivedEventAlready & currentDeviceIndex) == 0) // and device did not already receive an event in this method's call
                        {
                            // if (event_data.name.StartsWith("dd vibrator"))  // Debug
                            // {
                            //     Notification_Message?.Invoke(this, new StringArg(String.Format(
                            //         "Creating event {0} at part {1} with type {2}", event_data.name, bodyPart_id.ToString(), eventType_id.ToString())
                            //     ));
                            // }
                            runningEvents.Add(device.AddEvent(event_data.name, eventType.actions, synced_by_animation));
                            devicesReceivedEventAlready = devicesReceivedEventAlready | currentDeviceIndex;
                        }
                        currentDeviceIndex = currentDeviceIndex << 1;
                    }
                }
            }
            return(runningEvents);
        }
 public CheckBox_custom(CheckBox checkBox, Device.BodyPart bodyPart, Device.EventType eventType)
 {
     this.checkBox  = checkBox;
     this.bodyPart  = bodyPart;
     this.eventType = eventType;
 }