OSDN Git Service

28944840933b84171b7ba3f3163af8c866d19eb1
[pettanr/pettanr.git] / app / models / sheet_panel.rb
1 class SheetPanel < Peta::Element
2   load_manifest
3   belongs_to :author
4   belongs_to :panel
5   belongs_to :sheet
6   accepts_nested_attributes_for :panel, :allow_destroy => true
7   
8   validates :sheet_id, :numericality => {:allow_blank => true}
9   validates :panel_id, :numericality => {:allow_blank => true}
10   validates :author_id, :presence => true, :numericality => true, :existence => {:both => false}
11   validates :x, :presence => true, :numericality => true
12   validates :y, :presence => true, :numericality => true
13   validates :z, :presence => true, :numericality => {:greater_than => 0}
14   validates :t, :presence => true, :numericality => {:greater_than_or_equal_to => 0}
15   
16   def supply_default
17     self.x = 15
18     self.y = 15
19     if self.sheet
20       self.t = self.sheet.new_t 
21       self.z = self.sheet.new_z 
22     else
23       self.sheet_id = nil
24       self.panel_id = nil
25       self.z = 1
26       self.t = nil
27     end
28   end
29   
30   def overwrite operators
31     return false unless operators.author
32     self.author_id = operators.author.id
33   end
34   
35   def visible? operators
36     return false unless super
37     self.owner_model.visible? operators
38   end
39   
40   def self.list_where
41     'sheets.visible > 0'
42   end
43   
44   def self.list_order
45     'sheet_panels.updated_at desc'
46   end
47   
48   def self.play_list_where cid
49     ['sheet_panels.sheet_id = ?', cid]
50   end
51   
52   def self.play_list sheet, author
53     SheetPanel.where(self.play_list_where(sheet.id)).includes(SheetPanel.list_opt).order('sheet_panels.t')
54   end
55   
56   def self.list_opt
57     {
58       :author => {}, 
59       :sheet => {
60         :author => {}
61       }, 
62       :panel => {
63         :author => {}, 
64         :panel_pictures => {:picture => {:artist => {}, :license => {}}}, 
65         :speech_balloons =>{:balloon => {}, :speech => {}}
66       }
67     }
68   end
69   
70   def self.list_json_opt
71     {:include => {
72       :author => {}, 
73       :sheet => {
74         :author => {}
75       }, 
76       :panel => {
77         :author => {}, 
78         :panel_pictures => {:picture => {:artist => {}, :license => {}}}, 
79         :speech_balloons =>{:balloon => {}, :speech => {}}
80       }
81     }}
82   end
83   
84   def self.show_opt
85     {:include => {
86       :author => {}, 
87       :sheet => {
88         :author => {}
89       }, 
90       :panel => {
91         :author => {}, 
92         :panel_pictures => {:picture => {:artist => {}, :license => {}}}, 
93         :speech_balloons =>{:balloon => {}, :speech => {}}
94       }
95     }}
96   end
97   
98   def elements
99     self.panel.elements
100   end
101   
102   def sheet_panel_as_json au
103     panel_include = if self.panel and self.panel.visible?(au)
104       {:include => {:author => {}}, :methods => :elements}
105     else
106       {:include => {:author => {}}}
107     end
108     self.to_json({:include => {:sheet => {:include => {:author => {}}}, :author => {}, :panel => panel_include}})
109   end
110   
111   def self.list_as_json_text ary, au
112     '[' + ary.map {|i| i.sheet_panel_as_json(au) }.join(',') + ']'
113   end
114   
115   def licensed_pictures
116     if self.panel
117       self.panel.licensed_pictures
118     else
119       {}
120     end
121   end
122   
123     def self.panelize elements_attributes
124       elements_attributes = [elements_attributes] unless elements_attributes.is_a?(Array)
125       hash = {}
126       index = 0
127       elements_attributes.each do |element_attributes|
128         hash[self.to_s.tableize + '_attributes'] ||= {}
129         n = if element_attributes['id']
130           element_attributes['id'].to_s
131         else
132           index += 1
133           'new' + index.to_s 
134         end
135         hash[self.to_s.tableize + '_attributes'][n] = element_attributes
136       end
137       hash
138     end
139     
140     def copy_attributes
141       r = self.attributes
142       r.delete 'id'
143       r.delete 'sheet_id'
144       r.delete 'panel_id'   # create panel
145       r.delete 'created_at'
146       r.delete 'updated_at'
147       r
148     end
149   
150   def copyable?
151     if self.panel and self.panel.publish? == false
152       false
153     else
154       true
155     end
156   end
157   
158   def panel_attributes
159     if self.panel
160       {'panel_attributes' => self.panel.copy}
161     else
162       {}
163     end
164   end
165   
166   def self.new_t sheet_id
167     r = SheetPanel.max_t(sheet_id)
168     r.blank? ? 0 : r.to_i + 1
169   end
170   
171   def self.max_t sheet_id
172     SheetPanel.maximum(:t, :conditions => ['sheet_id = ?', sheet_id])
173   end
174   
175   def self.find_t sheet_id, t
176     SheetPanel.find(:first, :conditions => ['sheet_id = ? and t = ?', sheet_id, t])
177   end
178   
179   def self.collect_t sheet_panel
180     r = SheetPanel.find(:all, :conditions => ['sheet_id = ?', sheet_panel.sheet_id], :order => 't')
181     r.map {|sp| sp.t}
182   end
183   
184   def self.serial? ary
185     i = 0
186     ary.compact.sort.each do |t|
187       break false unless t == i
188       i += 1
189     end
190     ary.compact.size == i
191   end
192   
193   def self.validate_t sheet_panel
194     SheetPanel.serial?(SheetPanel.collect_t(sheet_panel))
195   end
196   
197   def insert_shift
198     SheetPanel.update_all('t = t + 1', ['sheet_id = ? and t >= ?', self.sheet_id, self.t])
199   end
200   
201   def lesser_shift old_t
202     self.t = 0 if self.t < 0
203     SheetPanel.update_all('t = t + 1', ['sheet_id = ? and (t >= ? and t < ?)', self.sheet_id, self.t, old_t])
204   end
205   
206   def higher_shift old_t
207     nf = SheetPanel.find_t(self.sheet_id, self.t)
208     max_t = SheetPanel.max_t(self.sheet_id).to_i
209     self.t = max_t if self.t > max_t
210     SheetPanel.update_all('t = t - 1', ['sheet_id = ? and (t > ? and t <= ?)', self.sheet_id, old_t, self.t])
211   end
212   
213   def update_shift old_t
214     if self.t > old_t
215       higher_shift old_t
216     else
217       lesser_shift old_t
218     end
219   end
220   
221   def rotate old_t = nil
222     if self.new_record?
223       if self.t.blank?
224         self.t = SheetPanel.new_t self.sheet_id
225       else
226         self.insert_shift
227       end
228     else
229       if self.t.blank?
230       else
231         self.update_shift old_t
232       end
233     end
234   end
235   
236   def allow? operators
237     return nil if self.sheet_id == nil or self.panel_id == nil
238     self.sheet.own?(operators) and self.panel.usable?(operators)
239   end
240   
241   def store operators, old_t = nil
242     res = false
243     SheetPanel.transaction do
244       case self.allow? operators
245       when true
246         self.rotate old_t
247       when false
248         raise ActiveRecord::Forbidden
249       else
250       end
251       res = self.save
252       raise ActiveRecord::Rollback unless res
253       res = SheetPanel.validate_t(self) 
254       unless res
255         self.errors.add :t, 'unserialized'
256         raise ActiveRecord::Rollback 
257       end
258     end
259     res
260   end
261   
262   def destroy_and_shorten
263     res = false
264     SheetPanel.transaction do
265       SheetPanel.update_all('t = t - 1', ['sheet_id = ? and (t > ?)', self.sheet_id, self.t])
266       raise ActiveRecord::Rollback unless self.destroy
267       res = true
268     end
269     res
270   end
271   
272 end