{groovy:output=wiki|showErrorOutput=true}

import com.atlassian.confluence.pages.Page;
import bucket.container.ContainerManager;

def index = request.getSession(true).getServletContext().getAttribute("climb.index")

if (index  == null )
{
  out.println "Creating index..."  
  index = new Index()

  String pageTitle="Climbing Guides"
  //String pageTitle="Hobart Craglets"
  Page page = ContainerManager.getComponent("pageManager").getPage(context.spaceKey,pageTitle);

  addChildren(page, index)
  request.getSession(true).getServletContext().setAttribute("climb.index", index)
}


def totalStars = ["","*","**","***"]
def totalGrades = ["10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","VE","V0","V1","V2","V3","V4","V5","V6","V7","V8","V9","V10","V11","V12","V13","V14","V15"]
def totalSorts = ["grade,stars,name","name","none"]


def sortBy = "grade,stars,name"
def grades = totalGrades //["17","18" ]
def stars = ["***"]
def pages = ["Far North","Northern Buttress","Rockaway and Amphitheatre","The Columns","Flange Buttress","Central Buttress","Great Tier","Step Tier","Teardrop Gully","Avalanche Couloir","University Buttress","Bulging Buttress","Broken Buttress","Lost World Area","Sphinx Rock","Ferntree","Other Crags"]


def nameStartsWith = ""
def nameContains = ""

if (request.getParameter("climb.search") != null )
{
  stars = toList( request.getParameterValues("climb.stars") )
  grades = toList( request.getParameterValues("climb.grades") )
  sortBy =  request.getParameter("climb.sortBy")
  nameStartsWith =  request.getParameter("climb.nameStartsWith")
  nameContains =  request.getParameter("climb.nameContains")
  pages = toList( request.getParameterValues("climb.pages") )
}


out.println '''
h2. Search Criteria
{info:title=Climb Search}This page lets you search the thesarvo guides by stars, grade, area etc. The criteria below all have to be satisfied, so you probably want to widen the criteria. The default search below shows the tick list of all the 3 star climbs on Mt Wellington. Use a Ctrl-click  to select multiple values for stars, grade and area. {info}
|| Stars || Name Starts With || Name Contains || Grade || Area || Sort By || 
| {html}
<form name='climb.form' method='post' >
<select multiple='true' name='climb.stars' >'''
for (a in totalStars)
{
  out.println "<option " + (stars.contains(a)?"selected":"") +  " value='" + a + "'>" + (a==""?"none":a) + "</option>"
}
out.println '''
</select>{html} | {html}
<input type='text' style='width:100px' name='climb.nameStartsWith' />
{html} | {html}
<input type='text' style='width:100px' name='climb.nameContains' />
{html} | {html}
<select multiple='true' size='8' name='climb.grades' >'''
for (a in totalGrades)
{
  out.println "<option " + (grades.contains(a)?"selected":"") +  " value='" + a + "'>" + a + "</option>"
}
out.println '''
{html} | {html}<select multiple='true' size='8' name='climb.pages' >'''
for (a in index.pages)
{
  out.println "<option " + (pages.contains(a)?"selected":"") +  " value='" + a + "'>" + a + "</option>"
}
out.println '''
</select>
{html} | {html}
<select name='climb.sortBy'>'''
for (a in totalSorts)
  out.println "<option " + (sortBy==a?"selected":"") +  " value='" + a + "'>" + a + "</option>"
out.println '''
</select>
{html} |
{html} <input type='submit' name='climb.search' value='Search..' /> </form>{html}
\\\\
'''

def filtered = new ArrayList();
for (c in index.climbs)
{
  if ( pages.contains(c.page) && grades.contains(c.grade) && stars.contains(c.stars) )
  {
    if (nameContains==null || nameContains.length()==0 || c.name.toLowerCase().contains(nameContains.toLowerCase()) )
    {
      if (nameStartsWith==null || nameStartsWith.length()==0 || c.name.toLowerCase().startsWith(nameStartsWith.toLowerCase()) )
      {
        if (grades==null || grades.size()==0)        
          filtered.add c
        else
          for (g in grades)
            if (c.grade!=null && c.grade.startsWith(g) )
            {
              filtered.add c
              break;
            }
      }
    }

  }
}

if (sortBy!=null && !sortBy.equals("none"))
{
  def compare = [ compare: {a,b-> a.name.toLowerCase().compareTo(b.name.toLowerCase()) } ] as Comparator

  if (sortBy.equals(totalSorts[0]))
  {
    compare = [ compare: {a,b-> a.getGradeSort().compareTo(b.getGradeSort() ) } ] as Comparator
  }
  //out.println "sorting"
  filtered.sort compare 
}

out.println "h2. Results"
out.println filtered.size + " results"
out.println "|| || Stars || Name || Length || Grade || Area ||"
for (c in filtered)
{
  out.println "| !check.jpg! | !http://www.thesarvo.com/confluence/download/resources/confluence.extra.guide:guide/" + c.stars.length() + "star.gif!" + " | " + c.name + " | " + c.length + " | " + c.grade + " | [" + c.page + "] |"
  //response.flushBuffer()
}

def addChildren(Page page, Index index)
{
  for (child in page.sortedChildren)
  {
    doPage(child, index)
  }
}

def doPage (Page page, Index index)
{
  int index1 = page.content.indexOf("{guide}")
  
  if (index1 > -1)
  {
    int index2 = page.content.indexOf("{guide}",index1+1)
    String xml = page.content.substring(index1+7, index2)
    //out.println ("Page:" + page )

    def x = new XmlParser().parseText(xml)
    def climbs = x.climb
    climbs.addAll x.problem

    if (climbs.size() > 0)
      index.pages.add page.title  

    for (climb in climbs)
    {


      Climb c = new Climb( name: climb.@name , 
grade: climb.@grade , 
stars: climb.@stars, 
length: climb.@length, 
page: page.title)
      c.stars = c.stars==null?"":c.stars
      c.stars = c.stars.trim()
      index.climbs.add( c )
    }

  }
  addChildren(page, index)
  

}

def List toList(x)
{
  def ret = []
  for (c in x)
    ret.add c

  return ret
}

class Index
{
  List climbs = []
  List pages = []
}

class Climb
{
  String name
  String grade
  String stars
  String length
  //String extra
  //String number
  String page 

  def getGradeSort()
  {
    return grade.trim() + stars.trim() + name.toLowerCase().trim() 
  }

  String toString()
  {
    return stars==null?"":stars + " " + "  " + length + "  " + grade 
  }
}

{groovy}