/*
  * CONSTRUCTORS
  * Allows you to define an attribute controlling either a single
  * channel, a list of channels, or a list of photons
  */
 public FixtureAttribute(ATTRIBUTE_TYPE Type, string Name, bool SnapOn, List<Photon> Photons, Fixture ParentFixture)
 {
     _type = Type;
     _name = Name;
     _snapOn = SnapOn;
     _photons = Photons;
     _parentFixture = ParentFixture;
 }
        public void PlayStep(Fixture fixture, RoutineStep step)
        {
            List<Point> movementPoints = step.GetPoints();
            List<AttributePoint> attributePoints = step.GetAttributePoints(movementPoints, fixture);
            double timePerPoint = step.Duration / movementPoints.Count;

            _playStep(fixture, step, movementPoints, attributePoints, timePerPoint);
        }
        public void PreviewStep(Fixture fixture, RoutineStep step)
        {
            List<Point> movementPoints = step.GetPoints();
            List<AttributePoint> attributePoints = step.GetAttributePoints(movementPoints, fixture);
            double timePerPoint = step.Duration / movementPoints.Count;

            PlayStepAsynchCaller caller = new PlayStepAsynchCaller(_playStep);
            caller.BeginInvoke(fixture, step, movementPoints, attributePoints, timePerPoint, null, null);
        }
        public FixtureAttribute(ATTRIBUTE_TYPE Type, string Name, bool SnapOn, int Channel, Fixture ParentFixture)
        {
            _type = Type;
            _name = Name;
            _snapOn = SnapOn;
            _photons = new List<Photon>();
            _parentFixture = ParentFixture;

            _photons.Add(new Photon(Channel, 255));
        }
        public AttributePoint(Point point, Fixture fixture)
        {
            _point = point;
            _popup = new AttributePointPopupControl();
            Draw(point.X, point.Y);

            _attributePointSettings = new ObservableCollection<AttributePointSetting>();
            foreach (FixtureAttribute attribute in fixture.Attributes)
            {
                _attributePointSettings.Add(new AttributePointSetting(attribute));
            }
        }
        public FixtureAttribute(ATTRIBUTE_TYPE Type, string Name, bool SnapOn, List<int> Channels, Fixture ParentFixture)
        {
            _type = Type;
            _name = Name;
            _snapOn = SnapOn;
            _photons = new List<Photon>();
            _parentFixture = ParentFixture;

            foreach (int chan in Channels)
            {
                _photons.Add(new Photon(chan, 255));
            }
        }
        private void _playStep(Fixture fixture, RoutineStep step, List<Point> movementPoints, List<AttributePoint> attributePoints, double timePerPoint)
        {
            for (int i = 0; i < step.RepeatCount; i++)
            {
                for (int j = 0; j < movementPoints.Count; j++)
                {
                    // First set the attribute values at this point
                    foreach (AttributePointSetting setting in attributePoints[j].AttributePointSettings)
                    {
                        setting.Attribute.SetLevel(setting.Value);
                    }

                    // Then tell the light to move
                    fixture.MoveTo(movementPoints[j], timePerPoint);
                }
            }
        }
 public FixtureAttribute(ATTRIBUTE_TYPE Type, string Name, int Channel, Fixture ParentFixture)
     : this(Type, Name, false, Channel, ParentFixture)
 {
 }
 public FixtureAttribute(ATTRIBUTE_TYPE Type, string Name, List<Photon> Photons, Fixture ParentFixture)
     : this(Type, Name, false, Photons, ParentFixture)
 {
 }
 // To restore one from a file
 public FixtureAttribute(SerializationInfo info, StreamingContext ctxt)
 {
     _type = (ATTRIBUTE_TYPE)info.GetValue("Type", typeof(ATTRIBUTE_TYPE));
     _name = info.GetString("Name");
     _snapOn = info.GetBoolean("SnapOn");
     _photons = (List<Photon>)info.GetValue("Photons", typeof(List<Photon>));
     _parentFixture = (Fixture)info.GetValue("parent", typeof(Fixture));
 }
 public FixtureWrapperFAOverride(Fixture fixture)
 {
     _fixture = fixture;
     _isAffected = false;
 }
 public RoutineFixture(SerializationInfo info, StreamingContext ctxt)
 {
     _fixture = (Fixture)info.GetValue("_fixture", typeof(Fixture));
     _routineSteps = (ObservableCollection<RoutineStep>)info.GetValue("_routineSteps", typeof(ObservableCollection<RoutineStep>)); // Will this preserve the order? Do collections have order?
     _referencePoints = (ObservableCollection<RoutineFixtureReferencePoint>)info.GetValue("_referencePoints", typeof(ObservableCollection<RoutineFixtureReferencePoint>));
 }
 public RoutineFixture(Fixture fixture)
 {
     _fixture = fixture;
     _routineSteps = new ObservableCollection<RoutineStep>();
     _referencePoints = new ObservableCollection<RoutineFixtureReferencePoint>();
 }
        public List<AttributePoint> GetAttributePoints(List<Point> movementPoints, Fixture fixture)
        {
            // Make a new list of attribute points, one per movement point
            List<AttributePoint> attrPoints = new List<AttributePoint>();
            foreach (Point pt in movementPoints)
            {
                attrPoints.Add(new AttributePoint(new Point(pt.X, pt.Y), fixture));
            }

            // Assign each attribute point to its closest movement point
            foreach (AttributePoint attrPt in _attributePoints)
            {
                int closestMovementPointIndex = Utilities.GetClosestPointIndexInList(attrPt.Point, movementPoints);
                attrPoints[closestMovementPointIndex] = attrPt;
            }

            // If there isn't a key attribute point assigned to the first movement point, we don't
            // know what value each fixture attribute should start at. So, we ask each fixture
            // attribute what its current DMX value is
            foreach (AttributePointSetting setting in attrPoints[0].AttributePointSettings)
            {
                if (!setting.Active)
                {
                    // If the setting isn't active, get the fixture attribute's current value
                    setting.Value = setting.Attribute.GetLevel();
                }
            }

            // Now fill in the intermediate values for the movement points that
            // don't have a corresponding attribute point.
            // First, we keep track of the last key point for each attribute, currently 0
            Dictionary<string, int> lastKeyPointForAttribute = new Dictionary<string, int>();
            foreach (FixtureAttribute attr in fixture.Attributes)
            {
                lastKeyPointForAttribute[attr.Name] = 0;
            }
            // Next, step through the attribute points; whenever we hit a "key" point
            // (that is, a point that has an active setting), if we were supposed to
            // fade to that value, go back and fill in the intermediate values
            for (int i = 0; i < attrPoints.Count; i++)
            {
                AttributePoint attrPoint = attrPoints[i];

                foreach (AttributePointSetting setting in attrPoint.AttributePointSettings)
                {
                    if (setting.Active)
                    {
                        if (!setting.Snap)
                        {
                            // If we aren't supposed to snap to this value, that means
                            // we were supposed to have been fading to it. So we have
                            // to go back and fill in the intermediate values between
                            // this AttributePoint and this attribute's last key point.
                            int lastKeyPointIndex = lastKeyPointForAttribute[setting.AttributeName];
                            int startVal = attrPoints[lastKeyPointIndex].GetSettingForAttributeName(setting.AttributeName).Value;
                            int endVal = setting.Value;
                            int incrementPerIntermediatePoint = (endVal - startVal) / (i - lastKeyPointIndex);

                            for (int j = lastKeyPointIndex + 1; j < i; j++)
                            {
                                AttributePointSetting intermediateSetting = attrPoints[j].GetSettingForAttributeName(setting.AttributeName);
                                intermediateSetting.Value = startVal + incrementPerIntermediatePoint * (j - lastKeyPointIndex);
                                intermediateSetting.Active = true;
                            }
                        }

                        // Since the setting is active, this is this attribute's
                        // most recent "key" attributePoint
                        lastKeyPointForAttribute[setting.AttributeName] = i;
                    }
                    else
                    {
                        // Since this is not a "key" point for this attribute, copy
                        // in the value from the last key point. It might turn out that
                        // we're supposed to be fading to the next key point here, but
                        // if this turns out to be the case, we'll come back and
                        // correct this point when we get the next key point

                        AttributePoint lastKeyPoint = attrPoints[lastKeyPointForAttribute[setting.AttributeName]];
                        setting.Value = lastKeyPoint.GetSettingForAttributeName(setting.AttributeName).Value;
                    }
                }
            }

            return attrPoints;
        }