private static AdDocumentPayload CreateDocument(IClipAdPayload mediaSource)
        {
            var adDocument     = new AdDocumentPayload();
            var adPod          = new AdPod();
            var ad             = new Ad();
            var linearCreative = new CreativeLinear();

            linearCreative.ClickThrough = mediaSource.ClickThrough;
            linearCreative.MediaFiles.Add(new MediaFile()
            {
                Type = mediaSource.MimeType, Value = mediaSource.MediaSource
            });
            ad.Creatives.Add(linearCreative);
            adPod.Ads.Add(ad);
            adDocument.AdPods.Add(adPod);
            return(adDocument);
        }
        private static void LoadVideoClicks(XElement vastLinear, CreativeLinear linearCreative)
        {
            if (vastLinear.Elements("VideoClicks").Any())
            {
                var videoClicks = vastLinear.Element("VideoClicks");

                linearCreative.ClickThrough = GetUriValue(videoClicks.Element("ClickThrough"));

                foreach (var clickTracking in videoClicks.Elements("ClickTracking"))
                {
                    linearCreative.ClickTracking.Add((string)clickTracking);
                }

                foreach (var customClick in videoClicks.Elements("CustomClick"))
                {
                    linearCreative.ClickTracking.Add((string)customClick);
                }
            }
        }
 private static AdDocumentPayload CreateDocument(IClipAdPayload mediaSource)
 {
     var adDocument = new AdDocumentPayload();
     var adPod = new AdPod();
     var ad = new Ad();
     var linearCreative = new CreativeLinear();
     linearCreative.ClickThrough = mediaSource.ClickThrough;
     linearCreative.MediaFiles.Add(new MediaFile() { Type = mediaSource.MimeType, Value = mediaSource.MediaSource });
     ad.Creatives.Add(linearCreative);
     adPod.Ads.Add(ad);
     adDocument.AdPods.Add(adPod);
     return adDocument;
 }
        private static void LoadVideoClicks(XElement vastLinear, CreativeLinear linearCreative)
        {
            if (vastLinear.Elements("VideoClicks").Any())
            {
                var videoClicks = vastLinear.Element("VideoClicks");

                linearCreative.ClickThrough = GetUriValue(videoClicks.Element("ClickThrough"));

                foreach (var clickTracking in videoClicks.Elements("ClickTracking"))
                {
                    linearCreative.ClickTracking.Add((string)clickTracking);
                }

                foreach (var customClick in videoClicks.Elements("CustomClick"))
                {
                    linearCreative.ClickTracking.Add((string)customClick);
                }
            }
        }
        private static void LoadCreatives(XElement adElement, Ad ad)
        {
            var vastCreatives = adElement.Element("Creatives");
            if (vastCreatives != null)
            {
                foreach (var vastCreative in vastCreatives.Elements("Creative"))
                {
                    var vastItem = vastCreative.Elements().FirstOrDefault();
                    if (vastItem != null)
                    {
                        ICreative creative = null;
                        switch (vastItem.Name.LocalName)
                        {
                            case "Linear":
                                var vastLinear = vastItem;
                                var linearCreative = new CreativeLinear();
                                creative = linearCreative;

                                foreach (var trackingEvent in GetTrackingEvents(vastLinear))
                                    linearCreative.TrackingEvents.Add(trackingEvent);

                                if (vastLinear.Elements("AdParameters").Any())
                                {
                                    var xmlEncoded = (bool?)vastLinear.Element("AdParameters").Attribute("xmlEncoded") ?? false;
                                    linearCreative.AdParameters = xmlEncoded ? XmlDecode((string)vastLinear.Element("AdParameters")) : (string)vastLinear.Element("AdParameters");
                                }

                                LoadVideoClicks(vastLinear, linearCreative);

                                if (vastLinear.Elements("CreativeExtensions").Any())
                                {
                                    foreach (var vastExtension in vastLinear.Element("CreativeExtensions").Elements("CreativeExtension"))
                                    {
                                        linearCreative.Extensions.Add(new Extension()); // TODO
                                    }
                                }

                                linearCreative.Duration = ToNullableTimeSpan((string)vastLinear.Element("Duration"));
                                linearCreative.SkipOffset = FlexibleOffset.Parse((string)vastLinear.Attribute("skipoffset"));

                                var vastIcons = vastLinear.Element("Icons");
                                if (vastIcons != null)
                                {
                                    foreach (var vastIcon in vastIcons.Elements("Icon"))
                                    {
                                        var icon = new Icon();

                                        if (vastIcon.Elements("IconClicks").Any())
                                        {
                                            var iconClicks = vastIcon.Element("IconClicks");

                                            icon.ClickThrough = GetUriValue(iconClicks.Element("IconClickThrough"));

                                            foreach (var clickTracking in iconClicks.Elements("IconClickTracking"))
                                            {
                                                icon.ClickTracking.Add((string)clickTracking);
                                            }
                                        }

                                        icon.ApiFramework = (string)vastIcon.Attribute("apiFramework") ?? string.Empty;
                                        icon.Duration = ToNullableTimeSpan((string)vastIcon.Attribute("duration")) ?? new TimeSpan?();
                                        icon.Height = (int?)vastIcon.Attribute("height");
                                        icon.Width = (int?)vastIcon.Attribute("width");
                                        icon.Offset = ToNullableTimeSpan((string)vastIcon.Attribute("offset")) ?? new TimeSpan?();
                                        icon.Program = (string)vastIcon.Attribute("program") ?? string.Empty;
                                        icon.XPosition = (string)vastIcon.Attribute("xPosition") ?? string.Empty;
                                        icon.YPosition = (string)vastIcon.Attribute("yPosition") ?? string.Empty;
                                        icon.Item = GetResources(vastIcon).FirstOrDefault();
                                        foreach (var viewTrackingUrl in vastIcon.Elements("IconViewTracking"))
                                        {
                                            icon.ViewTracking.Add((string)viewTrackingUrl);
                                        }
                                        linearCreative.Icons.Add(icon);
                                    }
                                }

                                if (vastLinear.Elements("MediaFiles").Any())
                                {
                                    foreach (var vastMedia in vastLinear.Element("MediaFiles").Elements("MediaFile"))
                                    {
                                        var mediaFile = new MediaFile();
                                        mediaFile.ApiFramework = (string)vastMedia.Attribute("apiFramework") ?? string.Empty;
                                        mediaFile.Bitrate = ToNullableLong((string)vastMedia.Attribute("bitrate"));
                                        mediaFile.Codec = (string)vastMedia.Attribute("codec") ?? string.Empty;
                                        mediaFile.Delivery = (MediaFileDelivery)Enum.Parse(typeof(MediaFileDelivery), (string)vastMedia.Attribute("delivery"), true);
                                        mediaFile.Height = (int?)vastMedia.Attribute("height") ?? 0;
                                        mediaFile.Width = (int?)vastMedia.Attribute("width") ?? 0;
                                        mediaFile.Id = (string)vastMedia.Attribute("id");
                                        mediaFile.MaintainAspectRatio = (bool?)vastMedia.Attribute("maintainAspectRatio") ?? false;
                                        mediaFile.MaxBitrate = (long?)vastMedia.Attribute("maxBitrate") ?? 0;
                                        mediaFile.MinBitrate = (long?)vastMedia.Attribute("minBitrate") ?? 0;
                                        mediaFile.Scalable = (bool?)vastMedia.Attribute("scalable") ?? false;
                                        mediaFile.Type = (string)vastMedia.Attribute("type");
                                        mediaFile.Value = GetUriValue(vastMedia);
                                        linearCreative.MediaFiles.Add(mediaFile);
                                    }
                                }
                                break;
                            case "CompanionAds":
                                var vastCompanions = vastItem;
                                creative = LoadCompanions(vastCompanions);
                                break;
                            case "NonLinearAds":
                                var vastNonLinears = vastItem;
                                var nonLinearCreative = new CreativeNonLinears();
                                creative = nonLinearCreative;

                                foreach (var trackingEvent in GetTrackingEvents(vastNonLinears))
                                    nonLinearCreative.TrackingEvents.Add(trackingEvent);

                                foreach (var vastNonLinear in vastNonLinears.Elements("NonLinear"))
                                {
                                    var nonLinear = new NonLinear();

                                    if (vastNonLinear.Elements("AdParameters").Any())
                                    {
                                        var xmlEncoded = (bool?)vastNonLinear.Element("AdParameters").Attribute("xmlEncoded") ?? false;
                                        nonLinear.AdParameters = xmlEncoded ? XmlDecode((string)vastNonLinear.Element("AdParameters")) : (string)vastNonLinear.Element("AdParameters");
                                    };
                                    nonLinear.ApiFramework = (string)vastNonLinear.Attribute("apiFramework");
                                    nonLinear.ClickThrough = GetUriValue(vastNonLinear.Element("NonLinearClickThrough"));
                                    foreach (var vastTracking in vastNonLinear.Elements("NonLinearClickTracking"))
                                    {
                                        nonLinear.ClickTracking.Add((string)vastTracking);
                                    }

                                    if (vastNonLinear.Elements("CreativeExtensions").Any())
                                    {
                                        foreach (var vastExtension in vastNonLinear.Element("CreativeExtensions").Elements("CreativeExtension"))
                                        {
                                            nonLinear.Extensions.Add(new Extension()); // TODO
                                        }
                                    }
                                    nonLinear.ExpandedHeight = (int?)vastNonLinear.Attribute("expandedHeight");
                                    nonLinear.ExpandedWidth = (int?)vastNonLinear.Attribute("expandedWidth");
                                    nonLinear.Height = (int?)vastNonLinear.Attribute("height") ?? 0;
                                    nonLinear.Width = (int?)vastNonLinear.Attribute("width") ?? 0;
                                    nonLinear.MaintainAspectRatio = (bool?)vastNonLinear.Attribute("maintainAspectRatio") ?? false;
                                    nonLinear.MinSuggestedDuration = ToNullableTimeSpan((string)vastNonLinear.Attribute("minSuggestedDuration")) ?? new TimeSpan?();
                                    nonLinear.Scalable = (bool?)vastNonLinear.Attribute("scalable") ?? false;
                                    nonLinear.Item = GetResources(vastNonLinear).FirstOrDefault();
                                    nonLinearCreative.NonLinears.Add(nonLinear);
                                }
                                break;
                        }
                        if (creative != null)
                        {
                            creative.AdId = (string)vastCreative.Attribute("AdID");
                            creative.Id = (string)vastCreative.Attribute("id");
                            creative.Sequence = ToNullableInt((string)vastCreative.Attribute("sequence"));
                            ad.Creatives.Add(creative);
                        }
                    }
                }
            }
        }
 internal LinearSource(CreativeLinear linear, MediaFile media)
 {
     Linear = linear;
     Media = media;
 }
        private static void LoadCreatives(XElement adElement, Ad ad)
        {
            var vastCreatives = adElement.Element("Creatives");

            if (vastCreatives != null)
            {
                foreach (var vastCreative in vastCreatives.Elements("Creative"))
                {
                    var vastItem = vastCreative.Elements().FirstOrDefault();
                    if (vastItem != null)
                    {
                        ICreative creative = null;
                        switch (vastItem.Name.LocalName)
                        {
                        case "Linear":
                            var vastLinear     = vastItem;
                            var linearCreative = new CreativeLinear();
                            creative = linearCreative;

                            foreach (var trackingEvent in GetTrackingEvents(vastLinear))
                            {
                                linearCreative.TrackingEvents.Add(trackingEvent);
                            }

                            if (vastLinear.Elements("AdParameters").Any())
                            {
                                var xmlEncoded = (bool?)vastLinear.Element("AdParameters").Attribute("xmlEncoded") ?? false;
                                linearCreative.AdParameters = xmlEncoded ? XmlDecode((string)vastLinear.Element("AdParameters")) : (string)vastLinear.Element("AdParameters");
                            }

                            LoadVideoClicks(vastLinear, linearCreative);

                            if (vastLinear.Elements("CreativeExtensions").Any())
                            {
                                foreach (var vastExtension in vastLinear.Element("CreativeExtensions").Elements("CreativeExtension"))
                                {
                                    linearCreative.Extensions.Add(new Extension());     // TODO
                                }
                            }

                            linearCreative.Duration   = ToNullableTimeSpan((string)vastLinear.Element("Duration"));
                            linearCreative.SkipOffset = FlexibleOffset.Parse((string)vastLinear.Attribute("skipoffset"));

                            var vastIcons = vastLinear.Element("Icons");
                            if (vastIcons != null)
                            {
                                foreach (var vastIcon in vastIcons.Elements("Icon"))
                                {
                                    var icon = new Icon();

                                    if (vastIcon.Elements("IconClicks").Any())
                                    {
                                        var iconClicks = vastIcon.Element("IconClicks");

                                        icon.ClickThrough = GetUriValue(iconClicks.Element("IconClickThrough"));

                                        foreach (var clickTracking in iconClicks.Elements("IconClickTracking"))
                                        {
                                            icon.ClickTracking.Add((string)clickTracking);
                                        }
                                    }

                                    icon.ApiFramework = (string)vastIcon.Attribute("apiFramework") ?? string.Empty;
                                    icon.Duration     = ToNullableTimeSpan((string)vastIcon.Attribute("duration")) ?? new TimeSpan?();
                                    icon.Height       = (int?)vastIcon.Attribute("height");
                                    icon.Width        = (int?)vastIcon.Attribute("width");
                                    icon.Offset       = ToNullableTimeSpan((string)vastIcon.Attribute("offset")) ?? new TimeSpan?();
                                    icon.Program      = (string)vastIcon.Attribute("program") ?? string.Empty;
                                    icon.XPosition    = (string)vastIcon.Attribute("xPosition") ?? string.Empty;
                                    icon.YPosition    = (string)vastIcon.Attribute("yPosition") ?? string.Empty;
                                    icon.Item         = GetResources(vastIcon).FirstOrDefault();
                                    foreach (var viewTrackingUrl in vastIcon.Elements("IconViewTracking"))
                                    {
                                        icon.ViewTracking.Add((string)viewTrackingUrl);
                                    }
                                    linearCreative.Icons.Add(icon);
                                }
                            }

                            if (vastLinear.Elements("MediaFiles").Any())
                            {
                                foreach (var vastMedia in vastLinear.Element("MediaFiles").Elements("MediaFile"))
                                {
                                    var mediaFile = new MediaFile();
                                    mediaFile.ApiFramework        = (string)vastMedia.Attribute("apiFramework") ?? string.Empty;
                                    mediaFile.Bitrate             = ToNullableLong((string)vastMedia.Attribute("bitrate"));
                                    mediaFile.Codec               = (string)vastMedia.Attribute("codec") ?? string.Empty;
                                    mediaFile.Delivery            = (MediaFileDelivery)Enum.Parse(typeof(MediaFileDelivery), (string)vastMedia.Attribute("delivery"), true);
                                    mediaFile.Height              = (int?)vastMedia.Attribute("height") ?? 0;
                                    mediaFile.Width               = (int?)vastMedia.Attribute("width") ?? 0;
                                    mediaFile.Id                  = (string)vastMedia.Attribute("id");
                                    mediaFile.MaintainAspectRatio = (bool?)vastMedia.Attribute("maintainAspectRatio") ?? false;
                                    mediaFile.MaxBitrate          = (long?)vastMedia.Attribute("maxBitrate") ?? 0;
                                    mediaFile.MinBitrate          = (long?)vastMedia.Attribute("minBitrate") ?? 0;
                                    mediaFile.Scalable            = (bool?)vastMedia.Attribute("scalable") ?? false;
                                    mediaFile.Type                = (string)vastMedia.Attribute("type");
                                    mediaFile.Value               = GetUriValue(vastMedia);
                                    linearCreative.MediaFiles.Add(mediaFile);
                                }
                            }
                            break;

                        case "CompanionAds":
                            var vastCompanions = vastItem;
                            creative = LoadCompanions(vastCompanions);
                            break;

                        case "NonLinearAds":
                            var vastNonLinears    = vastItem;
                            var nonLinearCreative = new CreativeNonLinears();
                            creative = nonLinearCreative;

                            foreach (var trackingEvent in GetTrackingEvents(vastNonLinears))
                            {
                                nonLinearCreative.TrackingEvents.Add(trackingEvent);
                            }

                            foreach (var vastNonLinear in vastNonLinears.Elements("NonLinear"))
                            {
                                var nonLinear = new NonLinear();

                                if (vastNonLinear.Elements("AdParameters").Any())
                                {
                                    var xmlEncoded = (bool?)vastNonLinear.Element("AdParameters").Attribute("xmlEncoded") ?? false;
                                    nonLinear.AdParameters = xmlEncoded ? XmlDecode((string)vastNonLinear.Element("AdParameters")) : (string)vastNonLinear.Element("AdParameters");
                                }
                                ;
                                nonLinear.ApiFramework = (string)vastNonLinear.Attribute("apiFramework");
                                nonLinear.ClickThrough = GetUriValue(vastNonLinear.Element("NonLinearClickThrough"));
                                foreach (var vastTracking in vastNonLinear.Elements("NonLinearClickTracking"))
                                {
                                    nonLinear.ClickTracking.Add((string)vastTracking);
                                }

                                if (vastNonLinear.Elements("CreativeExtensions").Any())
                                {
                                    foreach (var vastExtension in vastNonLinear.Element("CreativeExtensions").Elements("CreativeExtension"))
                                    {
                                        nonLinear.Extensions.Add(new Extension());     // TODO
                                    }
                                }
                                nonLinear.ExpandedHeight       = (int?)vastNonLinear.Attribute("expandedHeight");
                                nonLinear.ExpandedWidth        = (int?)vastNonLinear.Attribute("expandedWidth");
                                nonLinear.Height               = (int?)vastNonLinear.Attribute("height") ?? 0;
                                nonLinear.Width                = (int?)vastNonLinear.Attribute("width") ?? 0;
                                nonLinear.MaintainAspectRatio  = (bool?)vastNonLinear.Attribute("maintainAspectRatio") ?? false;
                                nonLinear.MinSuggestedDuration = ToNullableTimeSpan((string)vastNonLinear.Attribute("minSuggestedDuration")) ?? new TimeSpan?();
                                nonLinear.Scalable             = (bool?)vastNonLinear.Attribute("scalable") ?? false;
                                nonLinear.Item = GetResources(vastNonLinear).FirstOrDefault();
                                nonLinearCreative.NonLinears.Add(nonLinear);
                            }
                            break;
                        }
                        if (creative != null)
                        {
                            creative.AdId     = (string)vastCreative.Attribute("AdID");
                            creative.Id       = (string)vastCreative.Attribute("id");
                            creative.Sequence = ToNullableInt((string)vastCreative.Attribute("sequence"));
                            ad.Creatives.Add(creative);
                        }
                    }
                }
            }
        }
        internal static async Task<AdDocumentPayload> CreateFromVast1(XElement vastRoot, int? maxRedirectDepth, bool allowMultipleAds)
        {
            var result = new AdDocumentPayload();
            result.Version = (string)vastRoot.Attribute("version");

            foreach (var vastAdPod in vastRoot.Elements("Ad").GroupBy(va => va.Attribute("sequence") != null ? 1 : int.MaxValue).OrderBy(vap => vap.Key))
            {
                var adPod = new AdPod();
                foreach (var vastAd in vastAdPod.OrderBy(va => ToNullableInt((string)va.Attribute("sequence")).GetValueOrDefault(0)))
                {
                    var ad = new Ad();
                    ad.Id = (string)vastAd.Attribute("id");

                    if (vastAd.Elements("InLine").Any())
                    {
                        throw new NotImplementedException();
                    }
                    else if (vastAd.Elements("Wrapper").Any())
                    {
                        Ad wrapper = new Ad();
                        var vastAdWrapper = vastAd.Element("Wrapper");

                        // parse the wrapper itself
                        wrapper.AdSystem = GetAdSystem(vastAdWrapper.Element("AdSystem"));
                        var error = (string)vastAdWrapper.Element("Error");
                        if (error == null) wrapper.Errors.Add(error);

                        var linearCreative = new CreativeLinear();

                        foreach (var trackingEvent in GetTrackingEvents(vastAdWrapper))
                            linearCreative.TrackingEvents.Add(trackingEvent);

                        LoadVideoClicks(vastAdWrapper, linearCreative);

                        wrapper.Creatives.Add(linearCreative);

                        var vastAdUri = GetUriValue(vastAdWrapper.Element("VASTAdTagURL"));
                        if (vastAdUri != null)
                        {
                            // load the stream from the web
                            using (var s = await Extensions.LoadStreamAsync(vastAdUri))
                            {
                                int? nextMaxRedirectDepth = maxRedirectDepth.HasValue ? maxRedirectDepth.Value - 1 : maxRedirectDepth;
                                var vastDoc = await CreateFromVast(s, nextMaxRedirectDepth, allowMultipleAds);

                                var firstAdPodInChild = vastDoc.AdPods.FirstOrDefault();

                                if (firstAdPodInChild != null)
                                {
                                    // merge tracking info from this wrapper to every ad in the first adpod in the child
                                    foreach (Ad inlineAd in firstAdPodInChild.Ads)
                                        MergeWrappedAd(wrapper, inlineAd);

                                    // add each ad from the first adpod in the child to the current adpod
                                    foreach (Ad inlineAd in firstAdPodInChild.Ads)
                                        adPod.Ads.Add(inlineAd);
                                }
                            }
                        }
                    }
                }
                result.AdPods.Add(adPod);
            }
            return result;
        }
        static async Task<Ad> CreateLinearAd(FWAd source, FWAdReference reference)
        {
            var ad = new Ad();

            var allCallbacks = reference.EventCallbacks;
            foreach (var url in allCallbacks.Where(ec => ec.Type == FWCallbackType.Impression && ec.Name == FWEventCallback.DefaultImpression).SelectMany(ec => ec.GetUrls()))
            {
                ad.Impressions.Add(url);
            }

            int index = 0;
            IEnumerable<FWCreative> creatives = source.Creatives;
            if (reference.CreativeId != null)
            {
                creatives = creatives.Where(c => c.Id == reference.CreativeId);
            }
            foreach (var creative in creatives)
            {
                index++;
                var wrappedAds = new List<Ad>();
                var linear = new CreativeLinear();
                linear.AdParameters = string.Join("&", creative.Parameters.Select(p => Uri.EscapeDataString(p.Name) + "=" + Uri.EscapeDataString(p.Value)));
                linear.Duration = creative.Duration;
                linear.Sequence = index;

                IEnumerable<FWCreativeRendition> creativeRenditions = creative.CreativeRenditions;
                if (reference.CreativeRenditionId != null)
                {
                    creativeRenditions = creativeRenditions.Where(cr => cr.Id == reference.CreativeRenditionId).DefaultIfEmpty(creativeRenditions);
                    if (reference.ReplicaId != null)
                    {
                        creativeRenditions = creativeRenditions.Where(cr => cr.AdReplicaId == reference.ReplicaId).DefaultIfEmpty(creativeRenditions);
                    }
                }

                foreach (var rendition in creativeRenditions)
                {
                    if (!string.IsNullOrEmpty(rendition.WrapperType))
                    {
                        switch (rendition.WrapperType.ToLowerInvariant())
                        {
                            case "external/vast-2":
                                try
                                {
                                    var vastAdUri = new Uri(rendition.WrapperUrl);
                                    // load the stream from the web
                                    using (var s = await Extensions.LoadStreamAsync(vastAdUri))
                                    {
                                        var wrappedVastDoc = await AdModelFactory.CreateFromVast(s, null, true);
                                        if (wrappedVastDoc != null)
                                        {
                                            // use the first ad
                                            var wrappedAd = wrappedVastDoc.AdPods.SelectMany(pod => pod.Ads).FirstOrDefault();
                                            if (wrappedAd != null)
                                            {
                                                wrappedAds.Add(wrappedAd);
                                            }
                                        }
                                    }
                                }
                                catch { /* swallow */ }
                                break;
                        }
                    }
                    else
                    {
                        // TODO: FreeWheel assets can contain Content instead of Url. This could be supported someday; for now it is ignored.
                        if (rendition.Asset != null)
                        {
                            var mediaFile = CreateMediaFile(creative, rendition, rendition.Asset);
                            if (mediaFile != null)
                            {
                                mediaFile.Ranking = (int)rendition.Preference + 1; // add one to indicate this is preferred over "OtherAssets"
                                linear.MediaFiles.Add(mediaFile);
                            }
                        }

                        foreach (var asset in rendition.OtherAssets)
                        {
                            var mediaFile = CreateMediaFile(creative, rendition, asset);
                            if (mediaFile != null)
                            {
                                mediaFile.Ranking = (int)rendition.Preference;
                                linear.MediaFiles.Add(mediaFile);
                            }
                        }
                    }
                }

                // generate callback urls from one base url
                foreach (var eventCallback in allCallbacks.Where(ec => ec.Type == FWCallbackType.Impression))
                {
                    foreach (var url in eventCallback.GetUrls())
                    {
                        switch (eventCallback.Name.ToLower())
                        {
                            case "start":
                                linear.TrackingEvents.Add(new TrackingEvent() { Type = TrackingType.Start, Value = url });
                                break;
                            case "firstquartile":
                                linear.TrackingEvents.Add(new TrackingEvent() { Type = TrackingType.FirstQuartile, Value = url });
                                break;
                            case "midpoint":
                                linear.TrackingEvents.Add(new TrackingEvent() { Type = TrackingType.Midpoint, Value = url });
                                break;
                            case "thirdquartile":
                                linear.TrackingEvents.Add(new TrackingEvent() { Type = TrackingType.ThirdQuartile, Value = url });
                                break;
                            case "complete":
                                linear.TrackingEvents.Add(new TrackingEvent() { Type = TrackingType.Complete, Value = url });
                                break;
                        }
                    }
                }

                // generate callback urls from one base url
                foreach (var eventCallback in allCallbacks.Where(ec => ec.Type == FWCallbackType.Standard))
                {
                    foreach (var url in eventCallback.GetUrls())
                    {
                        switch (eventCallback.Name.Replace("-", "").ToLower())
                        {
                            case "_creativeview":
                                linear.TrackingEvents.Add(new TrackingEvent() { Type = TrackingType.CreativeView, Value = url });
                                break;
                            case "_mute":
                                linear.TrackingEvents.Add(new TrackingEvent() { Type = TrackingType.Mute, Value = url });
                                break;
                            case "_unmute":
                                linear.TrackingEvents.Add(new TrackingEvent() { Type = TrackingType.Unmute, Value = url });
                                break;
                            case "_pause":
                                linear.TrackingEvents.Add(new TrackingEvent() { Type = TrackingType.Pause, Value = url });
                                break;
                            case "_rewind":
                                linear.TrackingEvents.Add(new TrackingEvent() { Type = TrackingType.Rewind, Value = url });
                                break;
                            case "_resume":
                                linear.TrackingEvents.Add(new TrackingEvent() { Type = TrackingType.Resume, Value = url });
                                break;
                            case "_fullscreen":
                                linear.TrackingEvents.Add(new TrackingEvent() { Type = TrackingType.Fullscreen, Value = url });
                                break;
                            case "_exitfullscreen":
                                linear.TrackingEvents.Add(new TrackingEvent() { Type = TrackingType.ExitFullscreen, Value = url });
                                break;
                            case "_expand":
                                linear.TrackingEvents.Add(new TrackingEvent() { Type = TrackingType.Expand, Value = url });
                                break;
                            case "_collapse":
                                linear.TrackingEvents.Add(new TrackingEvent() { Type = TrackingType.Collapse, Value = url });
                                break;
                            case "_acceptinvitation":
                                linear.TrackingEvents.Add(new TrackingEvent() { Type = TrackingType.AcceptInvitation, Value = url });
                                break;
                            case "_close":
                                linear.TrackingEvents.Add(new TrackingEvent() { Type = TrackingType.Close, Value = url });
                                break;
                            case "_skip":
                                linear.TrackingEvents.Add(new TrackingEvent() { Type = TrackingType.Skip, Value = url });
                                break;
                            case "_progress":
                                linear.TrackingEvents.Add(new TrackingEvent() { Type = TrackingType.Progress, Value = url });
                                break;
                        }
                    }
                }

                foreach (var url in allCallbacks.Where(ec => ec.Type == FWCallbackType.Click && !ec.ShowBrowser).SelectMany(ec => ec.GetUrls()))
                {
                    linear.ClickTracking.Add(url);
                }

                var clickUrl = allCallbacks.Where(ec => ec.Type == FWCallbackType.Click && ec.ShowBrowser).SelectMany(ec => ec.GetUrls()).FirstOrDefault();
                if (clickUrl != null)
                {
                    linear.ClickThrough = new Uri(clickUrl);
                }

                // generate callback urls from one base url ONLY when the callback does not already exist
                foreach (var eventCallback in allCallbacks.Where(ec => ec.Type == FWCallbackType.Generic))
                {
                    foreach (var url in eventCallback.GetUrls())
                    {
                        var baseUrl = url + string.Format("&metr={0}", FreeWheelFactory.GetSupportedMetrics());

                        // quartile events
                        var quartileUrl = baseUrl + "&ct=[LASTQUARTILE]&et=i"; // [LASTQUARTILE] will get replaced by the VPAID controller
                        AddSecondaryCallback(linear.TrackingEvents, new TrackingEvent() { Type = TrackingType.FirstQuartile, Value = quartileUrl + "&cn=firstQuartile" });
                        AddSecondaryCallback(linear.TrackingEvents, new TrackingEvent() { Type = TrackingType.Midpoint, Value = quartileUrl + "&cn=midPoint" });
                        AddSecondaryCallback(linear.TrackingEvents, new TrackingEvent() { Type = TrackingType.ThirdQuartile, Value = quartileUrl + "&cn=thirdQuartile" });
                        AddSecondaryCallback(linear.TrackingEvents, new TrackingEvent() { Type = TrackingType.Complete, Value = quartileUrl + "&cn=complete" });

                        // advanced metrics
                        var advancedUrl = baseUrl + "&et=s";
                        AddSecondaryCallback(linear.TrackingEvents, new TrackingEvent() { Type = TrackingType.Mute, Value = advancedUrl + "&cn=_mute" });
                        AddSecondaryCallback(linear.TrackingEvents, new TrackingEvent() { Type = TrackingType.Unmute, Value = advancedUrl + "&cn=_un-mute" });
                        AddSecondaryCallback(linear.TrackingEvents, new TrackingEvent() { Type = TrackingType.Collapse, Value = advancedUrl + "&cn=_collapse" });
                        AddSecondaryCallback(linear.TrackingEvents, new TrackingEvent() { Type = TrackingType.Expand, Value = advancedUrl + "&cn=_expand" });
                        AddSecondaryCallback(linear.TrackingEvents, new TrackingEvent() { Type = TrackingType.Pause, Value = advancedUrl + "&cn=_pause" });
                        AddSecondaryCallback(linear.TrackingEvents, new TrackingEvent() { Type = TrackingType.Resume, Value = advancedUrl + "&cn=_resume" });
                        AddSecondaryCallback(linear.TrackingEvents, new TrackingEvent() { Type = TrackingType.Rewind, Value = advancedUrl + "&cn=_rewind" });
                        AddSecondaryCallback(linear.TrackingEvents, new TrackingEvent() { Type = TrackingType.AcceptInvitation, Value = advancedUrl + "&cn=_accept-invitation" });
                        AddSecondaryCallback(linear.TrackingEvents, new TrackingEvent() { Type = TrackingType.Close, Value = advancedUrl + "&cn=_close" });
                        //AddSecondaryCallback(linear.TrackingEvents, new TrackingEvent() { Type = TrackingType.Minimize, Value = advancedUrl + "&cn=_minimize" });
                    }
                }

                ad.Creatives.Add(linear);

                foreach (var wrappedAd in wrappedAds)
                {
                    AdModelFactory.MergeWrappedAdBeacons(wrappedAd, ad);
                    var wrappedCreative = AdModelFactory.FindMatchingCreative(linear, wrappedAd);
                    AdModelFactory.MergeWrappedCreative(wrappedCreative, linear);
                }
            }

            return ad;
        }
Exemple #10
0
 internal LinearSource(CreativeLinear linear, MediaFile media)
 {
     Linear = linear;
     Media  = media;
 }
Exemple #11
0
        internal static async Task <AdDocumentPayload> CreateFromVast1(XElement vastRoot, int?maxRedirectDepth, bool allowMultipleAds)
        {
            var result = new AdDocumentPayload();

            result.Version = (string)vastRoot.Attribute("version");

            foreach (var vastAdPod in vastRoot.Elements("Ad").GroupBy(va => va.Attribute("sequence") != null ? 1 : int.MaxValue).OrderBy(vap => vap.Key))
            {
                var adPod = new AdPod();
                foreach (var vastAd in vastAdPod.OrderBy(va => ToNullableInt((string)va.Attribute("sequence")).GetValueOrDefault(0)))
                {
                    var ad = new Ad();
                    ad.Id = (string)vastAd.Attribute("id");

                    if (vastAd.Elements("InLine").Any())
                    {
                        throw new NotImplementedException();
                    }
                    else if (vastAd.Elements("Wrapper").Any())
                    {
                        Ad  wrapper       = new Ad();
                        var vastAdWrapper = vastAd.Element("Wrapper");

                        // parse the wrapper itself
                        wrapper.AdSystem = GetAdSystem(vastAdWrapper.Element("AdSystem"));
                        var error = (string)vastAdWrapper.Element("Error");
                        if (error == null)
                        {
                            wrapper.Errors.Add(error);
                        }

                        var linearCreative = new CreativeLinear();

                        foreach (var trackingEvent in GetTrackingEvents(vastAdWrapper))
                        {
                            linearCreative.TrackingEvents.Add(trackingEvent);
                        }

                        LoadVideoClicks(vastAdWrapper, linearCreative);

                        wrapper.Creatives.Add(linearCreative);

                        var vastAdUri = GetUriValue(vastAdWrapper.Element("VASTAdTagURL"));
                        if (vastAdUri != null)
                        {
                            // load the stream from the web
                            using (var s = await Extensions.LoadStreamAsync(vastAdUri))
                            {
                                int?nextMaxRedirectDepth = maxRedirectDepth.HasValue ? maxRedirectDepth.Value - 1 : maxRedirectDepth;
                                var vastDoc = await CreateFromVast(s, nextMaxRedirectDepth, allowMultipleAds);

                                var firstAdPodInChild = vastDoc.AdPods.FirstOrDefault();

                                if (firstAdPodInChild != null)
                                {
                                    // merge tracking info from this wrapper to every ad in the first adpod in the child
                                    foreach (Ad inlineAd in firstAdPodInChild.Ads)
                                    {
                                        MergeWrappedAd(wrapper, inlineAd);
                                    }

                                    // add each ad from the first adpod in the child to the current adpod
                                    foreach (Ad inlineAd in firstAdPodInChild.Ads)
                                    {
                                        adPod.Ads.Add(inlineAd);
                                    }
                                }
                            }
                        }
                    }
                }
                result.AdPods.Add(adPod);
            }
            return(result);
        }