OSDN Git Service

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