# Ramaise Amrita, the Ramaze version of Reprise, a minimal hAtom blog
#   with Amrita2
#
# http://redflavor.com/reprise.rb
# http://www.rubyinside.com/reprise-a-ruby-powered-blogging-app-in-
#                            100-lines-including-templates-646.html
#
# Usage:
#
#   1. gem install ramaze bluecloth rubypants amrita2 -y
#   2. mkdir entries
#   3. vi entries/YYYY.MM.DD.Title.Goes.Here
#   4. ruby ramaise_amrita2.rb

%w(rubygems ramaze bluecloth rubypants amrita2).each{|lib| require lib }

class BlogPost
  include Amrita2::DictionaryData
  DIR = __DIR__/:entries

  def initialize filename
    raise 'Invalid BlogPost filename' unless File.exists?(filename)
    @filename, filename = filename, File.basename(filename)
    @date = Date.strptime(filename, '%Y.%m.%d').to_s
    @title = filename[11..-1].tr('.', ' ')
  end

  def body
    RubyPants.new(BlueCloth.new(File.read(@filename)).to_html).to_html
  end

  def slug
    @slug ||= title.gsub(/[^\w\s-]/, '').gsub(/\s+/, '-').downcase
  end

  attr_reader :date, :title

  class << self
    include Enumerable

    def each
      Dir[DIR/'*'].sort.reverse.each do |file| yield BlogPost.new(file) end
    end

    def [] key
      BlogPost.find{|post| post.slug == key }
    end
  end
end

class MainController < Ramaze::Controller
  include Amrita2

  TITLE = 'Ramaise with Amrita2 BLOG'
  AUTHOR = { :name => 'Taku Nakajima', :url => 'http://retro.brain-tokyo.net' }

  engine :Amrita2

  def index slug = nil
    title = nil
    if slug.nil?
      @posts = BlogPost.collect
      raise Ramaze::Error::NoAction,
            'No blog posts found, create
             entries/YYYY.MM.DD.My.First.Blog.Post' unless @posts.any?
    else
      raise Ramaze::Error::NoAction,
           'Invalid blog post' unless post = BlogPost[slug]
      post = BlogPost[slug]
      title = post.title
      @posts = [ post ]
    end

    title_hook = Amrita2::Core::Hook.new do
      if title
        render_child(:post_title, :href=>'/', :text=>title)
      else
        render_child(:index_title, :text=>TITLE)
      end
    end

    @data = binding

    %(
      <<h1 :title_hook | AcceptData[:hook] <
        <<a :post_title | Attr[:href] <
          <<:text>>
        <<span :index_title <
          <<:text>>

      <<div.hentry :posts <
        <<h2 { :url=> '/' + $_.slug } <
          <<abbr.updated title="$1" :| Eval["Time.parse($_.date).iso8601", :date] <
            $2
          <<a.entry-title href="$1" rel="bookmark" :| NVar[:url, :title] <
            $2
  
        <<div.entry-content :body | NoSanitize >>
    )
  end

  def error
    title = "#{TITLE}: Resource not found"
    message = Ramaze::Dispatcher::Error.current.message + '.'
    go_back = {
      :href => '/',
      :body => 'the front page.'
    }
    @data = binding
    %(
      <<h1 :title>>
      <<h2 :message>> 

      Go back to the
      <<a :go_back | Attr[:href, :body] >>
    )
  end

  def layout
    @data = binding
    %(
      <<html<
        <<head<
          <<title<
            %= TITLE  
            %= ': ' + @title if @title
          <<style type='text/css'<
            body {
              font-size: 90%;
              line-height: 1.4;
              width: 94%;
              margin: auto;
            }
    
            abbr { border: 0; }
    
            .entry-content {
              -moz-column-width: 30em;
              -moz-column-gap: 1.5em;
              -webkit-column-width: 30em;
              -webkit-column-gap: 1.5em;
            }
    
            h2 { border-bottom: 0.05em solid #999; }

        <<body<
          <<:content | NoSanitize >>
          <<address.author.vcard <
            <<a.url.fn :AUTHOR | Attr[:href=>:url, :body=>:name]>>
    )
  end
  layout :layout

end

Ramaze.start :sessions => false #, :adapter => :mongrel, :port => 3000
