@using Examine.SearchCriteria
@using OurUmbraco.Our
@using Umbraco.Core.Cache
@using OurUmbraco.Our.Examine
@using OurUmbraco.Project
@using OurUmbraco.Project.Services
@inherits Umbraco.Web.Macros.PartialViewMacroPage
@{
    //This is the main Our project search

    const int pagesToShowLeft = 4;
    var orderMode = !string.IsNullOrEmpty(Request["orderBy"]) ? Request["orderBy"] : "createDate";
    var page = !string.IsNullOrEmpty(Request["page"]) ? int.Parse(Request["page"]) : 1;
    var category = Request["category"];
    var version = Request["version"];
    var term = Request["term"];
    var pageSize = 20;
    var headline = orderMode == "createDate" ? "latest" : "most popular";
    if (version != null)
    {
        headline = "version " + version;
    }
    if (category != null)
    {
        headline = category == "uaas" ? "Umbraco as a Service" : category.ToLowerInvariant();
    }

    var searchFilters = new SearchFilters(BooleanOperation.And);
    //MUST be live
    searchFilters.Filters.Add(new SearchFilter("projectLive", "1"));
    var filters = new List<SearchFilters> { searchFilters };

    if (!string.IsNullOrEmpty(category))
    {
        var categoryFilters = new SearchFilters(BooleanOperation.Or);
        //NOTE: categories are indexed as lower case and are not tokenized so must be an exact match and therefore require quotes

        if (category.ToLowerInvariant() == "uaas".ToLowerInvariant())
        {
            categoryFilters.Filters.Add(new SearchFilter("worksOnUaaS", string.Format("\"{0}\"", "True")));
        }
        else
        {
            categoryFilters.Filters.Add(new SearchFilter("categoryFolder", string.Format("\"{0}\"", category.ToLowerInvariant().Trim())));
        }

        filters.Add(categoryFilters);
    }

    if (!string.IsNullOrEmpty(version))
    {
        //need to clean up this string, it could be all sorts of things
        var parsedVersion = version.GetFromUmbracoString();
        if (parsedVersion != null)
        {
            var fromVersion = parsedVersion.GetNumericalValue();
            var toVersion = new Version(parsedVersion.Major, 999, 999).GetNumericalValue();
            var versionFilters = new SearchFilters(BooleanOperation.Or);
            versionFilters.Filters.Add(new RangeSearchFilter("num_version", fromVersion, toVersion));
            versionFilters.Filters.Add(new RangeSearchFilter("num_compatVersions", fromVersion, toVersion));
            filters.Add(versionFilters);
        }
    }

    var examineOrder = orderMode;
    if (examineOrder == "popularity")
    {
        examineOrder = string.Concat(orderMode, "[Type=INT]");
    }
    else if (examineOrder == "createDate")
    {
        examineOrder = string.Concat(orderMode, "[Type=LONG]");
    }

    //TODO: cache for 1 minute with this key just need to ensure the enumerable in the result is finalized
    //var key = string.Format("ListProjects.{0}.{1}.{2}.{3}.{4}", page, orderMode, term, version, category);
    var searcher = new OurSearcher(term,
        "project", examineOrder,
        filters: filters, maxResults: pageSize * page);

    var search = searcher.Search("projectSearcher");
    var total = search.SearchResults.TotalItemCount;
    var pages = (total / pageSize) + 1;

    var url = string.Format("orderBy={0}&q={1}&version={2}&category={3}", orderMode, term, version, category);
    var result = search.SearchResults.Skip((page - 1) * pageSize).Take(pageSize);
}
@if (Context.IsDebuggingEnabled)
{
    <p style="border: 1px solid orange;">
        <strong>Debugging output</strong><br />
        <strong>Query:</strong> @search.LuceneQuery<br />
        <strong>Order by:</strong> @search.OrderBy<br />
        <strong>Time elapsed:</strong> @search.Totalmilliseconds<br />
        <strong>Total results:</strong> @total<br />
        <strong>Pages:</strong> @pages
    </p>
}
<div class="search-big">
    <input type="search" class="project-search-input" required placeholder="Search for projects">
    <label for="search">Search projects</label>
</div>
@functions{
    public string GetField(IDictionary<string, string> fields, string field, string defaultVal = "")
    {
        if (fields != null && fields.ContainsKey(field))
            return fields[field];

        return defaultVal;
    }

    public string ParseVersion(SearchResult result)
    {
        var versions = result.GetValues("versions").ToList();
        if (result.Fields.Keys.Contains("versions"))
        {
            versions.Add(result["versions"]);
        }

        var orderedVersions = versions
            .Select(x =>
            {
                Version v;
                return Version.TryParse(x, out v) ? v : null;
            }).WhereNotNull()
            .OrderByDescending(x => x)
            .ToArray();

        if (orderedVersions.Any() == false)
            return "n/a";

        if (orderedVersions.Length == 1)
            return orderedVersions.First() + "+";

        return orderedVersions.Min() + " - " + orderedVersions.Max();
    }
}
<h1>Browse @headline projects</h1>
<script type="text/template" class="search-item-project">
    <div class="box">
        <div class="row">
            <div class="col-xs-2 col-md-1">
                {[ if (image != null) { ]}
                <img src="{{image}}" alt="">
                {[ } else { ]}
                <i class='icon-Box'></i>
                {[ } ]}
            </div>
            <div class="col-xs-10 col-md-6">
                <div class="forum-thread-text">
                    <h3><a href="{{url}}">{{nodeName}}</a></h3>
                    <p>{{body}}</p>
                </div>
            </div>
            <div class="col-xs-12 col-md-5">
                <div class="other">
                    <div class="package-badge">
                        <span class="package-name">version</span>
                        <span class="package-number">{{versions}}</span>
                    </div>
                    <span class="stats">
                        <span class="downloads">
                            {{downloads}}<span><i class="icon-Download-alt"></i></span>
                        </span>
                        <span class="karma">
                            {{karma}}<span><i class="icon-Hearts"></i></span>
                        </span>
                    </span>
                </div>
            </div>
        </div>
    </div>
</script>
<div class="projects-search-listing"></div>
<div class="projects-default-listing">
    @foreach (var childPage in result)
    {
        var childContent = Umbraco.TypedContent(childPage.Id);
        if (childContent != null)
        {
            <div class="box">
                <div class="row">
                    <div class="col-xs-2 col-md-1">
                        @{
                            var defaultScreenshot = "/css/img/package2.png";
                            if (childContent != null)
                            {
                                defaultScreenshot = childContent.GetPropertyValue("defaultScreenshotPath", false, "/css/img/package2.png");
                            }
                        }
                        <img src="@Utils.GetScreenshotPath(defaultScreenshot)?bgcolor=fff&width=50&height=50&format=png" />
                    </div>
                    <div class="col-xs-10 col-md-6">
                        <div class="forum-thread-text">
                            <h3>
                                <a href="@childContent.Url">@childContent.Name</a>
                            </h3>
                            <p>@Html.Raw(GetField(childPage.Fields, "body", "No description available").StripHtml().Truncate(150))</p>
                        </div>
                    </div>
                    <div class="col-xs-12 col-md-5">

                        <div class="other">
                            <div class="package-badge">
                                <span class="package-name">version</span>
                                <span class="package-number">@ParseVersion(childPage)</span>
                            </div>
                            <span class="stats">
                                <span class="downloads">
                                    @GetField(childPage.Fields, "downloads", "0")<span><i class="icon-Download-alt"></i></span>
                                </span>
                                <span class="karma">
                                    @GetField(childPage.Fields, "karma", "0")<span><i class="icon-Hearts"></i></span>
                                </span>
                            </span>
                        </div>
                    </div>
                </div>
            </div>
                                }
                            }
    <nav class="pagination" role="navigation">
        @if (page > 1)
        {
            <a class="prev" href="?page=@(page - 1)&@url">Prev</a>
        }

        @for (var i = (page - 1 > 0 ? page - 1 : 1); i < (page + (pagesToShowLeft - (page - 1 > 0 ? 1 : 0))) && i <= pages; i++)
        {
            <a class="@Umbraco.If(i == page, "active")" href="?page=@i&@url">@i</a>
        }

        @if (page < pages)
        {
            <span>&hellip;</span>
            <a class="next" href="?page=@(page + 1)&@url">Next</a>
        }
    </nav>
</div>