# STV Explorer using Historical data from ASF Board Votes

#####
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#####

#
# Prereqs:
#
#   * svn checkout of foundation:voter and foundation:Meetings
#   * Web server with the ability to run cgi (Apache httpd recommended)
#   * Python 2.6.x
#   * Ruby 1.9.x
#   * wunderbar gem ([sudo] gem install wunderbar)
#   * (optional) jQuery http://code.jquery.com/jquery-min.js
#
# Installation instructions:
#
#    ruby whatif.rb --install=/var/www
#
#    1) Specify a path that supports cgi, like public-html or Sites.
#    2) (optional, but highly recommended) download jquery-min.js into
#       your installation directory.
#
# Execution instructions:
#
#   Point your web browser at your cgi script.  For best results, use
#   Firefox 4 or a WebKit based browser, like Google Chrome.



MEETINGS  = File.expand_path('../Meetings').untaint unless defined? MEETINGS
WHATIF = './whatif.py' unless defined? WHATIF

require 'wunderbar'
require 'tempfile'

def raw_votes(date)
  all_votes = Dir["#{MEETINGS}/*/raw_board_votes.txt"]
  if date
    result = "#{MEETINGS}/#{date}/raw_board_votes.txt"
  else
    result = all_votes.sort.last
  end
  result.untaint if all_votes.include? result
  result
end

def ini(vote)
  vote.sub('/raw_','/').sub('votes.','nominations.').sub('.txt','.ini')
end

def filtered_election(votes, seats, candidates)
  list = candidates.join(' ')
  list.untaint if list =~ /^\w+( \w+)*$/
  seats.untaint if seats =~ /^\d+$/

  output = `#{WHATIF} #{votes} #{seats} #{list}`
  output.scan(/.*elected$/).inject(Hash.new('none')) do |results, line|
    name, status = line.scan(/^(.*?)\s+(n?o?t?\s?elected)$/).flatten
    results.merge({name.gsub(/[^[[:alnum:]]]/,'') => status.gsub(/\s/, '-')})
  end
end

# XMLHttpRequest (AJAX)
_json do
  nominees = File.read(ini(raw_votes(@date))).scan(/^\w:\s*(.*)/).flatten
  candidates = params.keys & nominees.map {|name| name.gsub(/[^[[:alnum:]]]/,'')}
  _! filtered_election(raw_votes(@date), @seats, candidates)
end

# main output
_html do
  _head_ do
    _title 'STV Explorer'
    _style! %{
       h1 {font-family: sans-serif; font-weight: normal}
       select {display: block; margin: 0 0 1em 1em; font-size: 140%}
       label div {display: inline-block; min-width: 12em; font-size: x-large}
       label div {-webkit-transition: background-color 1s}
       label div {-moz-transition: background-color 1s}
       label {float: left; clear: both}
       label[for=seats] {display: inline; line-height: 500%}
       p, input[type=checkbox] {margin-left: 1em}
       p, input[type=submit] {display: block; clear: both}
       .elected {background: #0F0}
       .not-elected {background: #F00}
       .none {background: yellow}
    }
    _script src: 'assets/jquery-min.js'
  end

  _body? do
    _h1_ 'STV Explorer'

    nominees = Hash[File.read(ini(raw_votes(@date))).scan(/^\w:\s*(.*)/).
      flatten.map {|name| [name.gsub(/[^[[:alnum:]]]/,''), name]}]
    candidates = params.keys & nominees.keys
    candidates = nominees.keys if candidates.empty? or @reset

    @seats ||= '9'
    results = filtered_election(raw_votes(@date), @seats, candidates)

    # form of nominees and seats
    _form method: 'post', id: 'vote' do
      _select name: 'date' do
        Dir["#{MEETINGS}/*/raw_board_votes.txt"].sort.reverse.each do |votes|
	  next unless File.exist? ini(votes.untaint)
	  date = votes[/(\d+)\/raw_board_votes.txt$/,1]
          display = date.sub(/(\d{4})(\d\d)(\d\d)/,'\1-\2-\3')
          _option display, value: date, selected: (votes == raw_votes(@date))
	end
      end

      nominees.sort.each do |id, name|
        _label_ id: id do
          _input type: 'checkbox', name: id, checked: candidates.include?(id)
          _div name, class: results[id]
        end
      end

      _label_ for: 'seats' do
        _span 'seats:'
        _input name: 'seats', id: 'seats', value: @seats, size: 2,
          type: 'number', min: 1, max: nominees.length-1
      end

      _input type: 'submit', value: 'submit', name: 'submit'
    end

    _p_ do
      _a "Member's Meeting Information",
        href: 'https://whimsy.apache.org/members/meeting'
    end

    _script %{
      // submit form using XHR; update class for labels based on results
      function refresh() {
        $.post('', $('#vote').serialize(), function(results) {
          for (var name in results) {
            $('#'+name+' div').attr('class', results[name]);
          }
        }, 'json');
        return false;
      }

      // On checkbox click, remove class from associated label & refresh
      $(':checkbox').click(function() {
        $('div', $(this).parent()).attr('class', 'none');
        refresh();
      });

      // reset whenever the date changes
      $('select').change(function() {
        $('input[value=submit]').attr('name', 'reset');
        $('input[value=submit]').click();
      });

      // If JS is enabled, we don't need a submit button
      $('input[type=submit]').hide();

      // Refresh on change in number of seats
      $('#seats').on('input', function() {return refresh()});
    }
  end
end

__END__
MEETINGS = '../Meetings'
