OSDN Git Service

8dedbd6d8068936fe2f8717541130d4e2b9b0c19
[pettanr/pettanr.git] / lib / peta / leaf.rb
1 module Peta
2   class Leaf < Content
3     self.abstract_class = true
4     
5     # Dynamic ClassMethods
6     
7     def self.play_list_where cid
8       ['scroll_panels.scroll_id = ?', cid]
9     end
10     
11     def self.play_list scroll, author, offset = 0, limit = ScrollPanel.default_panel_size
12       ScrollPanel.where(self.play_list_where(scroll.id)).includes(ScrollPanel.list_opt).order('scroll_panels.t').offset(offset).limit(limit)
13     end
14     
15     def self.play_sheet_where sid
16       ['story_sheets.story_id = ?', sid]
17     end
18     
19     def self.play_sheet story, operators, page = 1
20       ss = StorySheet.where(self.play_sheet_where(story.id)).includes(StorySheet.list_opt).order('story_sheets.t').offset(page -1).limit(1).first
21       if ss 
22         if ss.sheet
23           Sheet.show(ss.sheet.id, operators)
24         else
25           nil
26         end
27       else
28         nil
29       end
30     end
31     
32     def self.play_paginate story, page
33       Kaminari.paginate_array(Array.new(StorySheet.where(self.play_sheet_where(story.id)).includes(StorySheet.list_opt).count, nil)).page(page).per(1)
34     end
35     
36     def self.new_t binder_id
37       r = ScrollPanel.max_t(binder_id)
38       r.blank? ? 0 : r.to_i + 1
39     end
40     
41     def self.max_t binder_id
42       self.class..maximum(:t, :conditions => ['scroll_id = ?', binder_id])
43     end
44     
45     def self.find_t binder_id, t
46       self.class.find(:first, :conditions => ['scroll_id = ? and t = ?', binder_id, t])
47     end
48     
49     def self.collect_t scroll_panel
50       r = self.class.find(:all, :conditions => ['scroll_id = ?', scroll_panel.scroll_id], :order => 't')
51       r.map {|sp| sp.t}
52     end
53     
54     def self.top_sheet story, author
55       StorySheet.play_list(story, author).first
56     end
57     
58     def self.collect_t story_sheet
59       r = StorySheet.find(:all, :conditions => ['story_id = ?', story_sheet.story_id], :order => 't')
60       r.map {|sp| sp.t}
61     end
62     
63     def self.serial? ary
64       i = 0
65       ary.compact.sort.each do |t|
66         break false unless t == i
67         i += 1
68       end
69       ary.compact.size == i
70     end
71     
72     def self.validate_t scroll_panel
73       ScrollPanel.serial?(ScrollPanel.collect_t(scroll_panel))
74     end
75     
76     def insert_shift
77       ScrollPanel.update_all('t = t + 1', ['scroll_id = ? and t >= ?', self.scroll_id, self.t])
78     end
79     
80     def lesser_shift old_t
81       self.t = 0 if self.t < 0
82       ScrollPanel.update_all('t = t + 1', ['scroll_id = ? and (t >= ? and t < ?)', self.scroll_id, self.t, old_t])
83     end
84     
85     def higher_shift old_t
86       nf = ScrollPanel.find_t(self.scroll_id, self.t)
87       max_t = ScrollPanel.max_t(self.scroll_id).to_i
88       self.t = max_t if self.t > max_t
89       ScrollPanel.update_all('t = t - 1', ['scroll_id = ? and (t > ? and t <= ?)', self.scroll_id, old_t, self.t])
90     end
91     
92     def update_shift old_t
93       if self.t > old_t
94         higher_shift old_t
95       else
96         lesser_shift old_t
97       end
98     end
99     
100     def rotate old_t = nil
101       if self.new_record?
102         if self.t.blank?
103           self.t = ScrollPanel.new_t self.scroll_id
104         else
105           self.insert_shift
106         end
107       else
108         if self.t.blank?
109         else
110           self.update_shift old_t
111         end
112       end
113     end
114     
115     def allow? operators
116       return nil if self.scroll_id == nil or self.panel_id == nil
117       self.scroll.own?(operators) and self.panel.usable?(operators)
118     end
119     
120     def destroy_and_shorten
121       res = false
122       ScrollPanel.transaction do
123         ScrollPanel.update_all('t = t - 1', ['scroll_id = ? and (t > ?)', self.scroll_id, self.t])
124         raise ActiveRecord::Rollback unless self.destroy
125         res = true
126       end
127       res
128     end
129     
130   end
131 end
132