OSDN Git Service

15612349179bc8cb78fd27e315602bebb3c352e1
[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.by_author_list_includes
57     {
58       :sheet => {
59         :author => {}
60       }
61     }
62   end
63   
64   def self.list_opt
65     {
66       :author => {}, 
67       :sheet => {
68         :author => {}
69       }, 
70       :panel => {
71         :author => {}, 
72         :panel_pictures => {:picture => {:artist => {}, :license => {}}}, 
73         :speech_balloons =>{:balloon => {}, :speech => {}}
74       }
75     }
76   end
77   
78   def self.list_json_opt
79     {:include => {
80       :author => {}, 
81       :sheet => {
82         :author => {}
83       }, 
84       :panel => {
85         :author => {}, 
86         :panel_pictures => {:picture => {:artist => {}, :license => {}}}, 
87         :speech_balloons =>{:balloon => {}, :speech => {}}
88       }
89     }}
90   end
91   
92   def self.show_opt
93     {:include => {
94       :author => {}, 
95       :sheet => {
96         :author => {}
97       }, 
98       :panel => {
99         :author => {}, 
100         :panel_pictures => {:picture => {:artist => {}, :license => {}}}, 
101         :speech_balloons =>{:balloon => {}, :speech => {}}
102       }
103     }}
104   end
105   
106   def elements
107     self.panel.elements
108   end
109   
110   def sheet_panel_as_json au
111     panel_include = if self.panel and self.panel.visible?(au)
112       {:include => {:author => {}}, :methods => :elements}
113     else
114       {:include => {:author => {}}}
115     end
116     self.to_json({:include => {:sheet => {:include => {:author => {}}}, :author => {}, :panel => panel_include}})
117   end
118   
119   def self.list_as_json_text ary, au
120     '[' + ary.map {|i| i.sheet_panel_as_json(au) }.join(',') + ']'
121   end
122   
123   def licensed_pictures
124     if self.panel
125       self.panel.licensed_pictures
126     else
127       {}
128     end
129   end
130   
131     def self.panelize elements_attributes
132       elements_attributes = [elements_attributes] unless elements_attributes.is_a?(Array)
133       hash = {}
134       index = 0
135       elements_attributes.each do |element_attributes|
136         hash[self.to_s.tableize + '_attributes'] ||= {}
137         n = if element_attributes['id']
138           element_attributes['id'].to_s
139         else
140           index += 1
141           'new' + index.to_s 
142         end
143         hash[self.to_s.tableize + '_attributes'][n] = element_attributes
144       end
145       hash
146     end
147     
148     def copy_attributes
149       r = self.attributes
150       r.delete 'id'
151       r.delete 'sheet_id'
152       r.delete 'panel_id'   # create panel
153       r.delete 'created_at'
154       r.delete 'updated_at'
155       r
156     end
157   
158   def copyable?
159     if self.panel and self.panel.publish? == false
160       false
161     else
162       true
163     end
164   end
165   
166   def panel_attributes
167     if self.panel
168       {'panel_attributes' => self.panel.copy}
169     else
170       {}
171     end
172   end
173   
174   def self.new_t sheet_id
175     r = SheetPanel.max_t(sheet_id)
176     r.blank? ? 0 : r.to_i + 1
177   end
178   
179   def self.max_t sheet_id
180     SheetPanel.maximum(:t, :conditions => ['sheet_id = ?', sheet_id])
181   end
182   
183   def self.find_t sheet_id, t
184     SheetPanel.find(:first, :conditions => ['sheet_id = ? and t = ?', sheet_id, t])
185   end
186   
187   def self.collect_t sheet_panel
188     r = SheetPanel.find(:all, :conditions => ['sheet_id = ?', sheet_panel.sheet_id], :order => 't')
189     r.map {|sp| sp.t}
190   end
191   
192   def self.serial? ary
193     i = 0
194     ary.compact.sort.each do |t|
195       break false unless t == i
196       i += 1
197     end
198     ary.compact.size == i
199   end
200   
201   def self.validate_t sheet_panel
202     SheetPanel.serial?(SheetPanel.collect_t(sheet_panel))
203   end
204   
205   def insert_shift
206     SheetPanel.update_all('t = t + 1', ['sheet_id = ? and t >= ?', self.sheet_id, self.t])
207   end
208   
209   def lesser_shift old_t
210     self.t = 0 if self.t < 0
211     SheetPanel.update_all('t = t + 1', ['sheet_id = ? and (t >= ? and t < ?)', self.sheet_id, self.t, old_t])
212   end
213   
214   def higher_shift old_t
215     nf = SheetPanel.find_t(self.sheet_id, self.t)
216     max_t = SheetPanel.max_t(self.sheet_id).to_i
217     self.t = max_t if self.t > max_t
218     SheetPanel.update_all('t = t - 1', ['sheet_id = ? and (t > ? and t <= ?)', self.sheet_id, old_t, self.t])
219   end
220   
221   def update_shift old_t
222     if self.t > old_t
223       higher_shift old_t
224     else
225       lesser_shift old_t
226     end
227   end
228   
229   def rotate old_t = nil
230     if self.new_record?
231       if self.t.blank?
232         self.t = SheetPanel.new_t self.sheet_id
233       else
234         self.insert_shift
235       end
236     else
237       if self.t.blank?
238       else
239         self.update_shift old_t
240       end
241     end
242   end
243   
244   def allow? operators
245     return nil if self.sheet_id == nil or self.panel_id == nil
246     self.sheet.own?(operators) and self.panel.usable?(operators)
247   end
248   
249   def store operators, old_t = nil
250     res = false
251     SheetPanel.transaction do
252       case self.allow? operators
253       when true
254         self.rotate old_t
255       when false
256         raise ActiveRecord::Forbidden
257       else
258       end
259       res = self.save
260       raise ActiveRecord::Rollback unless res
261       res = SheetPanel.validate_t(self) 
262       unless res
263         self.errors.add :t, 'unserialized'
264         raise ActiveRecord::Rollback 
265       end
266     end
267     res
268   end
269   
270   def destroy_and_shorten
271     res = false
272     SheetPanel.transaction do
273       SheetPanel.update_all('t = t - 1', ['sheet_id = ? and (t > ?)', self.sheet_id, self.t])
274       raise ActiveRecord::Rollback unless self.destroy
275       res = true
276     end
277     res
278   end
279   
280 end