@inherits umbraco.MacroEngines.DynamicNodeContext
@using System.Globalization
@using System.Text.RegularExpressions
@using OurUmbraco.MarketPlace.Models
@using OurUmbraco.Our
@using uForum.Businesslogic
@{
    var queriedVersion = Request.QueryString["v"];
    int requestedVersion;
    int.TryParse(queriedVersion, out requestedVersion);
    Version properVersion = null;

    if (requestedVersion != 0)
    {
        properVersion = GetProperVersion(requestedVersion.ToString(CultureInfo.InvariantCulture));
    }

    var projectGroups = Model.Children.Where("nodeTypeAlias == \"ProjectGroup\"");
    var projects = new List<UmbracoProject>();

    foreach (var projectGroup in projectGroups)
    {
        foreach (var project in projectGroup.Children)
        {
            if (project.projectLive)
            {
                var versionsList = new List<int>();
                var compatibleVersions = project.CompatibleVersions.Split(',');
                foreach (var compatibleVersion in compatibleVersions)
                {
                    if (string.IsNullOrWhiteSpace(compatibleVersion) == false && compatibleVersion != "saved")
                    {
                        int version;
                        if (int.TryParse(compatibleVersion.Substring(1), out version))
                        {
                            versionsList.Add(version);
                        }
                    }
                }

                var umbracoProject = new UmbracoProject
                                     {
                                         Id = project.Id,
                                         Name = project.Name,
                                         CreateDate = project.CreateDate,
                                         CompatibleVersions = versionsList
                                     };

                projects.Add(umbracoProject);
            }
        }
    }

    if (requestedVersion == 0)
    {
        <div class="deliPromoBox clearfix">
            @{
                var vs = new List<int>();
                foreach (var project in projects.OrderByDescending(x => x.CreateDate))
                {
                    foreach (var version in project.CompatibleVersions.Where(version => vs.Contains(version) == false))
                    {
                        vs.Add(version);
                    }
                }

                foreach (var v in vs.OrderBy(x => x).Where(x => x.ToString(CultureInfo.InvariantCulture).StartsWith("3") == false && x.ToString(CultureInfo.InvariantCulture).StartsWith("5") == false).Skip(6))
                {
                    <a href="/Projects/ProjectsVersioned?v=@v">Umbraco @(GetProperVersion(v.ToString(CultureInfo.InvariantCulture)).ToString(2)).x</a><br />
                }
            }
        </div>
    }
    else
    {
        <h1 class="deliCatHead">Umbraco @(properVersion.ToString(2)).x compatible projects</h1>
        <p><strong>Note:</strong> packages higher up in this list are more likely to actually work as they have been reported <br />to be working with Umbraco version @(properVersion.ToString(2)).x.</p>
        <div class="deliPromoBox clearfix">
            <div class="deliPromoArea">
                <div class="deliPromoBox new clearfix">

                    @{
                        var vs = new List<int>();
                        foreach (var project in projects.OrderByDescending(x => x.CreateDate))
                        {
                            foreach (var version in project.CompatibleVersions.Where(version => vs.Contains(version) == false))
                            {
                                vs.Add(version);
                            }
                        }
                    }
                    <ul class="promoOptions">
                        @foreach (var v in vs.OrderBy(x => x).Where(x => x.ToString(CultureInfo.InvariantCulture).StartsWith("3") == false && x.ToString(CultureInfo.InvariantCulture).StartsWith("5") == false).Skip(6))
                        {
                            var itemProperVersion = GetProperVersion(v.ToString(CultureInfo.InvariantCulture)).ToString(2);
                            var currentProperVersion = properVersion.ToString(2);

                            <li><a href="?v=@v" class="newnav @(itemProperVersion == currentProperVersion ? "on": null)">@(itemProperVersion).x</a></li>
                        }
                    </ul>

                    @{
                        var projectIds = projects.Where(x => x.CompatibleVersions.Contains(requestedVersion)).Select(x => x.Id).ToArray();
                        var selection = string.Join(",", projectIds);
                        if (string.IsNullOrWhiteSpace(selection) == false)
                        {
                            var reader = Data.SqlHelper.ExecuteReader("SELECT id, nodeId, downloads FROM wikiFiles WHERE type = 'package' AND nodeId IN (" + selection + ")");

                            while (reader.Read())
                            {
                                var project = projects.FirstOrDefault(x => x.Id == reader.GetInt("nodeId"));

                                if (project != null)
                                {
                                    project.TotalDownloads = project.TotalDownloads + reader.GetInt("downloads");
                                    project.FileId = reader.GetInt("id");
                                }
                            }

                            reader = Data.SqlHelper.ExecuteReader("SELECT id, SUM([points]) AS Karma FROM powersProject WHERE id IN (" + selection + ") GROUP BY Id");

                            while (reader.Read())
                            {
                                var project = projects.FirstOrDefault(x => x.Id == reader.GetInt("id"));

                                if (project != null)
                                {
                                    project.Karma = reader.GetInt("Karma");
                                }
                            }

                            var i = 1;
                            foreach (var project in projects.OrderBy(x => x.TotalDownloads).Where(x => x.CompatibleVersions.Contains(requestedVersion)))
                            {
                                project.TotalDownloadsRank = i + 5;
                                i++;
                            }

                            i = 1;
                            foreach (var project in projects.OrderBy(x => x.DownloadsCurrentVersion).Where(x => x.CompatibleVersions.Contains(requestedVersion)))
                            {
                                project.CurrentVersionDownloadsRank = i + 10;
                                i++;
                            }

                            i = 1;
                            foreach (var project in projects.OrderBy(x => x.Karma).Where(x => x.CompatibleVersions.Contains(requestedVersion)))
                            {
                                project.KarmaRank = i + 5;
                                i++;
                            }

                            foreach (var project in projects.Where(x => x.CompatibleVersions.Contains(requestedVersion)))
                            {
                                project.TotalRank = project.TotalDownloadsRank + project.CurrentVersionDownloadsRank + project.KarmaRank;
                            }

                            var fileIds = projects.Where(x => x.CompatibleVersions.Contains(requestedVersion)).Select(x => x.FileId).ToArray();
                            selection = string.Join(",", fileIds);

                            reader = Data.SqlHelper.ExecuteReader("SELECT * FROM DeliVersionCompatibility WHERE fileID IN(" + selection + ") AND version LIKE '" + GetProperVersion(requestedVersion.ToString(CultureInfo.InvariantCulture)).ToString(2) + ".%'");

                            while (reader.Read())
                            {
                                var project = projects.FirstOrDefault(x => x.Id == reader.GetInt("projectId"));

                                if (project != null)
                                {
                                    project.ReportsCount++;

                                    if (reader.GetBoolean("isCompatible"))
                                    {
                                        project.CompatibilityCount++;
                                    }
                                }
                            }

                            var totalProjects = projects.Count(x => x.CompatibleVersions.Contains(requestedVersion));
                            foreach (var project in projects.Where(x => x.CompatibleVersions.Contains(requestedVersion)))
                            {
                                if (project.ReportsCount > 0 && project.CompatibilityCount == 0)
                                {
                                    project.TotalRank = -30;
                                    continue;
                                }

                                if (project.ReportsCount > 0)
                                {
                                    project.TotalRank = project.TotalRank + (project.CompatibilityCount + totalProjects);

                                    float compats = project.CompatibilityCount;
                                    float numReps = project.ReportsCount;
                                    var percentage = compats/numReps;
                                    project.CompatibilityScore = percentage;
                                    project.TotalRank = (int) (project.TotalRank*percentage);
                                }
                            }
                            

                            <p class="viewAll">Showing @totalProjects projects</p>
                        }
                    }

                    <ul id="newest-projects">

                        @foreach (var project in projects.OrderByDescending(x => x.TotalRank).Where(x => x.CompatibleVersions.Contains(requestedVersion)))
                        {
                            var node = Library.NodeById(project.Id);
                            var description = node.Description.ToString();
                            var category = node.Parent.Name;
                            var screenshot = node.DefaultScreenshotPath.ToString();
                            var icon = string.IsNullOrEmpty(screenshot)
                                ? "/css/img/package2.png"
                                : string.Format("image={0}?bgcolor=fff&width=50&height=50&format=png", screenshot);

                            <li class="clearfix">
                                <div class="deliPackage">
                                    <div class="brief">
                                        <a href="@node.Url" class="packageIcon" style="background:url(@icon) no-repeat top left;">Package</a>
                                        <h3><a href="@node.Url">@project.Name</a></h3>
                                        <div class="category">@category</div>
                                        <div class="commercialIndicator @node.ListingType">@node.ListingType</div>
                                    </div>

                                    <div class="hiLite">
                                        <p><a href="@node.Url">@(ShortenText(description))</a></p>
                                    </div>

                                    <div class="popularity">
                                        <div class="karma">
                                            @project.Karma <small>Karma</small>
                                        </div>
                                        <div class="downloads">
                                            @project.TotalDownloads <small>Downloads</small>
                                        </div>
                                    </div>
                                </div>
                            </li>
                        }
                    </ul>

                </div>
            </div>
        </div>
    }
}

@functions {
    public Version GetProperVersion(string version)
    {
        if (version == "4.1.0")
        {
            return new Version(version);
        }

        version = version.Replace(".", "");

        if (version.EndsWith("x"))
        {
            version = version.Substring(0, version.IndexOf("x", StringComparison.Ordinal));
        }

        if (version == "410" || version == "4100")
        {
            return new Version("4.10");
        }

        if (version == "411" || version == "4110")
        {
            return new Version("4.11");
        }

        if (version.EndsWith("x"))
        {
            version = version.Substring(0, version.IndexOf("x", StringComparison.Ordinal) - 1);
        }

        var splitVersion = version.ToCharArray();
        version = string.Join(".", splitVersion);

        if (version.Length == 1)
        {
            version = version + ".0";
        }

        var tempRevision = new Version(version);

        return tempRevision.Revision == -1 ? new Version(tempRevision.Major, tempRevision.Minor, 0) : tempRevision;
    }

    public static string ShortenText(string text)
    {
        text = Utils.StripHTML(text).Replace("&nbsp;", "");
        if (text.Length > 210)
        {

            text = text.Substring(0, 210);
            text = text.Substring(0, text.LastIndexOf(' '));
        }

        text = Regex.Replace(text, @"[^a-zA-Z0-9\s.?!&;]", ""); //strip all crap from the listing such as ======================================= !!!!
        return text.Trim();
    }
}
