Росен обнови решението на 06.11.2013 00:07 (преди около 11 години)
+module Parser
+ def self.format(list)
+ list.map do |item|
+ item[0] = item[0].downcase.to_sym
+ item[2] = item[2].downcase.to_sym
+ item[3] = item[3].gsub(/, +/, ',').strip.split(",")
+ end
+ end
+
+ def self.create_tasks(list)
+ format(list)
+ tasks = []
+ 1.upto(list.length).each { tasks << Task.new }
+ tasks.each_with_index { |item, index| item.task = list[index] }
+ end
+end
+
+module Filter
+ def filter(norm)
+ # filter = []
+ # @list.each do |task|
+ # norm.each { |crit| filter << task if Filter.contains? task.task, crit }
+ # end
+ # TodoList.new(filter.uniq)
+ end
+
+ def self.contains?(task, other)
+ return true if other.empty?
+ return task.flatten.include? other if not other.instance_of? Array
+ return contains? task, other.drop(1) if task.flatten.include? other.first
+ false
+ end
+end
+
+module Statistics
+ def tasks_todo
+ count = 0
+ each { |item| count += item.count(:todo) }
+ count
+ end
+
+ def tasks_in_progress
+ count = 0
+ each { |item| count += item.count(:current) }
+ count
+ end
+
+ def tasks_completed
+ count = 0
+ each { |item| count += item.count(:done) }
+ count
+ end
+
+ def completed?
+ completed = true
+ each { |item| completed = item.task[0] == :done }
+ completed
+ end
+end
+
+class TodoList
+ include Enumerable
+ include Filter
+ include Statistics
+ attr_accessor :list
+
+ def initialize(value = [])
+ @list = value
+ end
+
+ def each
+ @list.each { |item| yield item }
+ end
+
+ def self.parse(text)
+ list = []
+ text.each_line { |line| list << line.gsub(/[ ]*[|][ ]*/, '|').split("|") }
+ TodoList.new(Parser.create_tasks(list))
+ end
+
+ def adjoin(other)
+ TodoList.new((@list + other.list).uniq { |item| item.task[1] })
+ end
+end
+
+class Criteria
+ include Enumerable
+ attr_accessor :criteria
+
+ def initialize(value)
+ @criteria = value
+ end
+
+ def Criteria.status(value)
+ Criteria.new([value]) if [:todo, :current, :done].include? value
+ end
+
+ def Criteria.priority(value)
+ Criteria.new([value]) if [:low, :normal, :high].include? value
+ end
+
+ def Criteria.tags(value)
+ Criteria.new(value)
+ end
+
+ def |(other)
+ Criteria.new([@criteria] + [other.criteria])
+ end
+
+ def &(other)
+ Criteria.new([@criteria + other.criteria])
+ end
+
+ def !
+ puts "wow such ! much filter so criteria"
+ end
+
+ def each
+ @criteria.each { |item| yield item }
+ end
+end
+
+class Task
+ include Enumerable
+ attr_accessor :task
+
+ def each
+ @task.each { |item| yield item }
+ end
+
+ def status
+ task[0]
+ end
+
+ def description
+ task[1]
+ end
+
+ def priority
+ task[2]
+ end
+
+ def tags
+ task[3]
+ end
+end