protected void Page_Load(object sender, EventArgs e)
        {
            using (var ctx = new EF.RepositoryContext("LogoDB"))
            {
                List<object> suggestions = new List<object>();

                foreach (var suggestion in ctx.Suggestions.Include("Channels").Include("Aliases").Include("Aliases.Channel").Include("Logos").Include("Logos.Channels").Include("User").OrderByDescending(s => s.LastModified))
                {
                    EF.Suggestion.SuggestionType suggestWhat;
                    EF.Channel channel = suggestion.GetSuggestedChannel(out suggestWhat);
                    
                    string channelName = string.Format("{0} ({1})", channel.Name, channel.Type);

                    suggestions.Add(new 
                    {
                        Id = suggestion.Id,
                        Creation = suggestion.Created.ToString("dd.MM.yyyy hh:mm"), 
                        Type = string.Format("New {0}", suggestWhat),
                        Channel = channelName, 
                        UserName = suggestion.User != null ? suggestion.User.Login : "",
                        Region = channel.RegionCode,
                        Aliases = string.Join(", ", suggestion.Aliases.Select(a => a.Name)),
                        Description = channel.Description,
                        Logo = suggestion.Logos.FirstOrDefault()
                    });
                }

                gvSuggestions.DataSource = suggestions;
                gvSuggestions.DataBind();
            }
        }
        protected void btnAddMessage_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrWhiteSpace(tbxNewMessage.Text))
            {
                Guid suggestionId = GetSuggestionIdFromRequest();
                if (suggestionId != Guid.Empty)
                {
                    using (var ctx = new EF.RepositoryContext("LogoDB"))
                    {
                        var suggestion = ctx.Suggestions.Include("Messages").FirstOrDefault(s => s.Id == suggestionId);
                        if (suggestion != null)
                        {
                            suggestion.Messages.Add(new EF.Message() 
                            {
                                Id = Guid.NewGuid(),
                                Created = DateTime.Now,
                                Suggestion = suggestion,
                                Text = tbxNewMessage.Text.Trim()
                            });
                            ctx.ChangeTracker.DetectChanges();
                            ctx.SaveChanges();

                            tbxNewMessage.Text = "";
                            gvMessages.DataSource = suggestion.Messages;
                            gvMessages.DataBind();
                        }
                    }
                }
            }
        }
 public Dictionary<string, string> GetLogos(List<string> channelsNames, ChannelType type, string regionCode)
 {
     var result = new Dictionary<string, string>();
     using (var ctx = new EF.RepositoryContext("LogoDB"))
     {
         foreach (var channelName in channelsNames)
         {
             var aliases = ctx.Aliases.Include("Channel").Include("Channel.Logos").Include("Channel.Logos.Suggestion").Where(a => a.Name == channelName && a.Channel.Type == type);
             if (aliases.Any())
             {
                 if (!string.IsNullOrWhiteSpace(regionCode))
                 {
                     // find best matching by RegionCode
                     var matchedByRegion = aliases.FirstOrDefault(a => a.Channel.RegionCode == regionCode);
                     if (matchedByRegion != null)
                     {
                         result.Add(channelName, matchedByRegion.Channel.Logos.First(l => l.Suggestion == null).Id.ToString());
                         continue;
                     }
                 }
                 // simply use first one
                 result.Add(channelName, aliases.First().Channel.Logos.First(l => l.Suggestion == null).Id.ToString());
             }
         }
     }
     return result;
 }
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                using (var ctx = new EF.RepositoryContext("LogoDB"))
                {
                    var suggestion = GetSuggestion(ctx);
                    if (suggestion != null)
                    {
                        EF.Suggestion.SuggestionType suggestWhat;
                        EF.Channel channel = suggestion.GetSuggestedChannel(out suggestWhat);

                        lblSuggestionDate.Text = suggestion.Created.ToString("dd.MM.yyyy hh:mm");
                        lblSuggestWhat.Text = string.Format("Suggestion for a new {0}", suggestWhat);
                        lblChannelName.Text = string.Format("{0} ({1})", channel.Name, channel.Type);
                        linkChannel.NavigateUrl = channel.Website;
                        linkChannel.Text = channel.Website;
                        linkChannel.Visible = !string.IsNullOrEmpty(channel.Website);
                        lblChannelRegion.Text = channel.RegionCode;
                        lblChannelDescription.Text = channel.Description;

                        var logoNew = suggestion.Logos.FirstOrDefault();
                        if (logoNew != null)
                        {
                            imgChannelLogoNew.Visible = true;
                            imgChannelLogoNew.ImageUrl = string.Format("/Logos/{0}.png", logoNew.Id);
                            imgChannelLogoNew.NavigateUrl = string.Format("/Logos/{0}.png", logoNew.Id);
                            lblLogoMetadataNew.Text = string.Format("{0}x{1}, {2:F1}KB", logoNew.Width, logoNew.Height, logoNew.SizeInBytes / 1024.0);
                            lblLogoMetadataNew.Visible = true;
                            lblNewLogo.Visible = true;
                        }
                        
                        var logoOld = channel.Logos.FirstOrDefault(l => l.Suggestion == null);
                        if (logoOld != null)
                        {
                            imgChannelLogoOld.Visible = true;
                            imgChannelLogoOld.ImageUrl = string.Format("/Logos/{0}.png", logoOld.Id);
                            imgChannelLogoOld.NavigateUrl = string.Format("/Logos/{0}.png", logoOld.Id);
                            lblLogoMetadataOld.Text = string.Format("{0}x{1}, {2:F1}KB", logoOld.Width, logoOld.Height, logoOld.SizeInBytes / 1024.0);
                            lblLogoMetadataOld.Visible = true;
                            if (logoNew != null) lblOldLogo.Visible = true;
                        }

                        string oldAliases = string.Join(", ", channel.Aliases.Where(a => a.Suggestion == null).Select(a => a.Name));
                        string newAliases = string.Join(", ", channel.Aliases.Where(a => a.Suggestion == suggestion).Select(a => a.Name));
                        lblChannelOldAliases.Text = oldAliases;
                        lblChannelNewAliases.Text = newAliases;
                        lblChannelOldAliases.Visible = oldAliases != "";
                        lblChannelNewAliases.Visible = newAliases != "";

                        gvMessages.DataSource = suggestion.Messages;
                        gvMessages.DataBind();
                    }
                }
            }
        }
 protected void btnShowAliases_Click(object sender, EventArgs e)
 {
     using (var ctx = new EF.RepositoryContext("LogoDB"))
     {
         var providerGuid = Guid.Parse(ddProviders.SelectedValue);
         var aliases = ctx.Aliases.Include("Channel").Where(a => a.Providers.Any(p => p.Id == providerGuid)).OrderBy(a => a.Name).ToList();
         gvAliases.DataSource = aliases;
         gvAliases.DataBind();
     }
 }
        protected void Page_Load(object sender, EventArgs e)
        {
            if (IsPostBack)
                return;

            using (var ctx = new EF.RepositoryContext("LogoDB"))
            {
                var list = ctx.Providers.OrderBy(p => p.Name).ToList();
                ddProviders.DataSource = list;
                ddProviders.DataBind();
            }
        }
 protected void btnShowChannels_Click(object sender, EventArgs e)
 {
     string region = ddRegion.SelectedValue;
     var type = (ChannelType)byte.Parse(rblChannelType.SelectedValue);
     if (!string.IsNullOrWhiteSpace(region))
     {
         using (var ctx = new EF.RepositoryContext("LogoDB"))
         {
             var list = ctx.Channels.Include("Logos").Include("Logos.Suggestion").Include("Aliases").Include("Aliases.Providers").Where(c => c.Suggestion == null && c.RegionCode == region && c.Type == type).OrderBy(c => c.Name).ToList();
             gvChannels.DataSource = list;
             gvChannels.DataBind();
         }
     }
 }
        protected void Page_Load(object sender, EventArgs e)
        {
            if (IsPostBack)
                return;

            rblChannelType.DataSource = Enum.GetNames(typeof(ChannelType)).Select((value, index) => new { value, index }).ToDictionary(pair => pair.value, pair => pair.index);
            rblChannelType.DataBind();
            rblChannelType.SelectedIndex = 0;

            using (var ctx = new EF.RepositoryContext("LogoDB"))
            {
                var list = ctx.Channels.Where(c => c.Suggestion == null).Select(c => c.RegionCode).Distinct().OrderBy(r => r).ToList();
                ddRegion.DataSource = list;
                ddRegion.DataBind();
            }
        }
        protected void btnSearch_Click(object sender, EventArgs e)
        {
            IQueryable<EF.Alias> aliases = null;
            using (var ctx = new EF.RepositoryContext("LogoDB"))
            {
                var type = (ChannelType)byte.Parse(rblChannelType.SelectedValue);

                aliases = ctx.Aliases.Include("Channel").Include("Channel.Logos").Include("Channel.Logos.Suggestion").Include("Providers").Where(a => a.Name == tbxName.Text && a.Channel.Type == type);
                if (!string.IsNullOrWhiteSpace(tbxRegion.Text) && aliases.Any())
                {
                    // limit results to be matching by RegionCode
                    aliases = aliases.Where(a => a.Channel.RegionCode == tbxRegion.Text);
                }
                gvLogos.DataSource = aliases.ToList();
                gvLogos.DataBind();
            }
        }
        protected void btnDecline_Click(object sender, EventArgs e)
        {
            Guid suggestionId = GetSuggestionIdFromRequest();
            if (suggestionId != Guid.Empty)
            {
                using (var ctx = new EF.RepositoryContext("LogoDB"))
                {
                    var suggestion = ctx.Suggestions
                        .Include("Channels")
                        .Include("Messages")
                        .Include("Aliases")
                        .Include("Logos")
                        .FirstOrDefault(s => s.Id == suggestionId);

                    if (suggestion != null)
                    {
                        var logoFilesToDelete = suggestion.Logos.Select(l => l.Id).ToList();

                        ctx.Channels.RemoveRange(suggestion.Channels);
                        ctx.Logos.RemoveRange(suggestion.Logos);
                        ctx.Aliases.RemoveRange(suggestion.Aliases);
                        ctx.Messages.RemoveRange(suggestion.Messages);
                        ctx.Suggestions.Remove(suggestion);

                        ctx.ChangeTracker.DetectChanges();
                        ctx.SaveChanges();

                        logoFilesToDelete.ForEach(l => {
                            var logoFilePath = Path.Combine(Server.MapPath("~/Logos"), l + ".png");
                            if (File.Exists(logoFilePath))
                                File.Delete(logoFilePath);
                            var logoThumbPath = Thumbnailer.GetThumbFilePath(l);
                            if (File.Exists(logoThumbPath))
                                File.Delete(logoThumbPath);
                        });

                        Response.Redirect("/ListSuggestions.aspx", false);
                        HttpContext.Current.ApplicationInstance.CompleteRequest();
                        this.Visible = false;
                    }
                }
            }
        }
        protected void btnApprove_Click(object sender, EventArgs e)
        {
            Guid suggestionId = GetSuggestionIdFromRequest();
            if (suggestionId != Guid.Empty)
            {
                using (var ctx = new EF.RepositoryContext("LogoDB"))
                {
                    var suggestion = ctx.Suggestions
                        .Include("Channels")
                        .Include("Messages")
                        .Include("Aliases")
                        .Include("Logos").Include("Logos.Channels").Include("Logos.Channels.Logos")
                        .FirstOrDefault(s => s.Id == suggestionId);
                    if (suggestion != null)
                    {
                        foreach (var channel in suggestion.Channels) channel.Suggestion = null;
                        if (suggestion.Logos.Any())
                        {
                            // delete the old logo (DB object and files) on the channel when suggestion was new logo
                            foreach(var logo in suggestion.Logos.First().Channels.First().Logos.Where(l => l.Suggestion == null).ToList())
                            {
                                logo.Repository = null;
                                logo.Creator = null;
                                ctx.Logos.Remove(logo);
                                File.Delete(Thumbnailer.GetThumbFilePath(logo.Id));
                                File.Delete(Path.Combine(Server.MapPath("~/Logos"), logo.Id + ".png"));
                            }
                        }
                        foreach (var logo in suggestion.Logos) logo.Suggestion = null;
                        foreach (var alias in suggestion.Aliases) alias.Suggestion = null;
                        ctx.Messages.RemoveRange(suggestion.Messages);
                        ctx.Suggestions.Remove(suggestion);

                        ctx.ChangeTracker.DetectChanges();
                        ctx.SaveChanges();

                        Response.Redirect("/ListSuggestions.aspx", false);
                        HttpContext.Current.ApplicationInstance.CompleteRequest();
                        this.Visible = false;
                    }
                }
            }
        }
        protected void btnImport_Click(object sender, EventArgs e)
        {
            var errors = new List<string>();
            txtInfo.Text = "";

            try
            {
                if (!Uri.IsWellFormedUriString(tbxUrl.Text, UriKind.Absolute))
                    errors.Add("Mapping File Url is not a valid Url!");
                if (!Uri.IsWellFormedUriString(tbxRadioLogosBaseUrl.Text, UriKind.Absolute))
                    errors.Add("Radio Logos Base Url is not a valid Url!");
                if (!Uri.IsWellFormedUriString(tbxTVLogosBaseUrl.Text, UriKind.Absolute))
                    errors.Add("TV Logos Base Url is not a valid Url!");
                if (!tbxUrl.Text.ToLower().EndsWith(".xml"))
                    errors.Add("Mapping File Url must point to a xml file!");

                var mappings = new XmlDocument();
                mappings.Load(tbxUrl.Text);

                var xmlTvChannels = new List<Tuple<Dictionary<string, HashSet<string>>, string, EF.Logo>>();
                var xmlRadioChannels = new List<Tuple<Dictionary<string, HashSet<string>>, string, EF.Logo>>();

                using (var ctx = new EF.RepositoryContext("LogoDB"))
                {
                    var tvChannels = mappings.SelectSingleNode("Mappings/TV");
                    foreach (XmlElement tvChannel in tvChannels.SelectNodes("Channel"))
                    {
                        var xmlTvChannel = GetChannel(tvChannel, 0, ctx, ref errors);
                        if (xmlTvChannel != null)
                            xmlTvChannels.Add(xmlTvChannel);
                    }

                    var radioChannels = mappings.SelectSingleNode("Mappings/Radio");
                    foreach (XmlElement radioChannel in radioChannels.SelectNodes("Channel"))
                    {
                        var xmlRadioChannel = GetChannel(radioChannel, 1, ctx, ref errors);
                        if (xmlRadioChannel != null)
                            xmlRadioChannels.Add(xmlRadioChannel);
                    }

                    EF.User currentUser = null;
                    var membership = System.Web.Security.Membership.GetUser();
                    if (membership != null)
                        currentUser = ctx.Users.FirstOrDefault(u => u.Id == (Guid)membership.ProviderUserKey);

                    var repo = ctx.Repositorys.FirstOrDefault();

                    var allProviders = ctx.Providers.ToDictionary(p => p.Name, p => p);

                    foreach (var importChannel in xmlTvChannels)
                    {
                        CreateDbChannel(importChannel, ChannelType.Tv, ctx, repo, currentUser, allProviders);
                    }
                    foreach (var importChannel in xmlRadioChannels)
                    {
                        CreateDbChannel(importChannel, ChannelType.Radio, ctx, repo, currentUser, allProviders);
                    }

                    ctx.ChangeTracker.DetectChanges();
                    ctx.SaveChanges();
                }

                txtInfo.Text = string.Format("Imported {0} TV and {1} Radio Channels.", xmlTvChannels.Count, xmlRadioChannels.Count);
            }
            catch (Exception ex)
            {
                errors.Add(ex.Message);
            }
            listErrors.DataSource = errors;
            listErrors.DataBind();
            listErrors.Visible = errors.Count > 0;
        }
        protected void btnSubmit_Click(object sender, EventArgs e)
        {
            try
            {
                using (var ctx = new EF.RepositoryContext("LogoDB"))
                {
                    var repo = ctx.Repositorys.FirstOrDefault();

                    var suggestion = ctx.Suggestions.Create();
                    suggestion.Id = Guid.NewGuid();
                    suggestion.Created = DateTime.Now;
                    suggestion.LastModified = DateTime.Now;
                    
                    var membership = System.Web.Security.Membership.GetUser();
                    if (membership != null)
                        suggestion.User = ctx.Users.FirstOrDefault(u => u.Id == (Guid)membership.ProviderUserKey);

                    if (!string.IsNullOrEmpty(tbxSuggestionInfo.Text.Trim()))
                        suggestion.Messages.Add(new Message() { Id = Guid.NewGuid(), Created = DateTime.Now, Suggestion = suggestion, Text = tbxSuggestionInfo.Text.Trim(), User = suggestion.User });
                    repo.Suggestions.Add(suggestion);

                    Channel channel = null;
                    if (TabContainer1.ActiveTab == tabPanelNewChannel)
                    {
                        string channelName = tbxChannelName.Text.Trim();
                        var channelType = (ChannelType)byte.Parse(rblChannelType.SelectedValue);

                        if (string.IsNullOrEmpty(channelName))
                            throw new Exception("Please give the new Channel an unique name!");

                        if (ctx.Channels.Any(c => c.Name == channelName && c.Type == channelType))
                            throw new Exception(string.Format("A {0}-Channel '{1}' already exists!", channel.Type, channelName));

                        string channelWebsite = tbxChannelWebsite.Text.Trim();
                        if (!string.IsNullOrEmpty(channelWebsite) && !channelWebsite.Contains("://"))
                            channelWebsite = "http://" + channelWebsite;

                        channel = ctx.Channels.Create();
                        channel.Id = Guid.NewGuid();
                        channel.Suggestion = suggestion;
                        channel.Name = channelName;
                        channel.Website = channelWebsite;
                        channel.RegionCode = ddlChannelRegion.SelectedValue;
                        channel.Description = tbxChannelDescription.Text.Trim();
                        channel.Type = channelType;
                        repo.Channels.Add(channel);
                    }
                    else
                    {
                        string channelName = listFoundChannels.SelectedValue;
                        if (string.IsNullOrEmpty(channelName))
                            throw new Exception("Please select an existing Channel!");
                        channel = ctx.Channels.Include("Aliases").Include("Logos").FirstOrDefault(c => c.Name == channelName);
                    }

                    foreach (ListItem newAlias in listNewAliases.Items)
                    {
                        string newAliasTrimmed = newAlias.Value.Trim();
                        if (!string.IsNullOrEmpty(newAliasTrimmed))
                        {
                            if (!channel.Aliases.Any(a => a.Name == newAliasTrimmed))
                            {
                                var alias = ctx.Aliases.Create();
                                alias.Id = Guid.NewGuid();
                                alias.Name = newAliasTrimmed;
                                alias.Created = DateTime.Now;
                                alias.Channel = channel;
                                channel.Aliases.Add(alias);
                                alias.Suggestion = suggestion;
                            }
                        }
                    }

                    if (channel.Aliases.Count == 0)
                        throw new Exception("A Channel must have at least one Alias");

                    if (uploadLogoFile.HasFile)
                    {
                        // check that file is PNG
                        byte[] logoData = uploadLogoFile.FileBytes;
                        using (MemoryStream ms = new MemoryStream(logoData))
                        {
                            using (System.Drawing.Image image = System.Drawing.Image.FromStream(ms, true, true))
                            {
                                if (image.RawFormat.Guid != System.Drawing.Imaging.ImageFormat.Png.Guid)
                                {
                                    throw new Exception("The supplied Logo file is not a valid PNG image!");
                                }
                                else
                                {
                                    var logo = ctx.Logos.Create();
                                    logo.Id = Guid.NewGuid();
                                    logo.Name = tbxLogoName.Text.Trim();
                                    if (string.IsNullOrEmpty(logo.Name))
                                        throw new Exception("Please give the new Logo an unique name!");
                                    logo.Origin = tbxLogoOrigin.Text.Trim();
                                    logo.LastModified = DateTime.Now;
                                    logo.Width = image.Width;
                                    logo.Height = image.Height;
                                    logo.SizeInBytes = logoData.Length;
                                    repo.Logos.Add(logo);
                                    logo.Suggestion = suggestion;
                                    logo.Creator = suggestion.User;
                                    logo.Channels.Add(channel);
                                    File.WriteAllBytes(Path.Combine(Server.MapPath("~/Logos"), logo.Id + ".png"), logoData);
                                    Thumbnailer.CreateLogoThumb(image, logo.Id);
                                }
                            }
                        }
                    }

                    ctx.ChangeTracker.DetectChanges();

                    if (channel.Logos.Count == 0)
                        throw new Exception("Please specify a logo for the new Channel!");

                    if (!suggestion.Channels.Any() && !suggestion.Aliases.Any() && !suggestion.Logos.Any())
                        throw new Exception("Please suggest at least a new logo or new alias!");
                    
                    ctx.SaveChanges();

                    Response.Redirect(Request.Url.AbsoluteUri, false);
                    HttpContext.Current.ApplicationInstance.CompleteRequest();
                    this.Visible = false;
                }
            }
            catch (Exception ex)
            {
                lblReturnMessage.Visible = true;
                lblReturnMessage.Text = ex.Message;
            }
        }
 protected void listFoundChannels_SelectedIndexChanged(object sender, EventArgs e)
 {
     panelSelectedChannelInfo.Visible = (sender as ListBox).SelectedIndex > -1;
     string channelName = (sender as ListBox).SelectedValue;
     using (var ctx = new EF.RepositoryContext("LogoDB"))
     {
         var channel = ctx.Channels.Include("Aliases").FirstOrDefault(c => c.Name == channelName);
         if (channel != null)
         {
             lblSelectedChannelRegion.Text = channel.RegionCode;
             linkSelectedChannel.NavigateUrl = channel.Website;
             linkSelectedChannel.Text = channel.Website;
             lblSelectedChannelDescription.Text = channel.Description;
             lblSelectedChannelType.Text = Enum.GetName(typeof(ChannelType), channel.Type);
             lbSelectedChannelAliases.Items.Clear();
             foreach(var alias in channel.Aliases)
                 lbSelectedChannelAliases.Items.Add(alias.Name);
             lbSelectedChannelAliases.Visible = lbSelectedChannelAliases.Items.Count > 0;
         }
     }
 }
 protected void btnSearch_Click(object sender, EventArgs e)
 {
     listFoundChannels.Items.Clear();
     string search = tbxChannelSearch.Text.Trim();
     using (var ctx = new EF.RepositoryContext("LogoDB"))
     {
         foreach(var channelName in ctx.Channels.Where(c => c.Suggestion == null && c.Name.Contains(search)).Select(c => c.Name))
             listFoundChannels.Items.Add(channelName);
     }
 }