OSDN Git Service

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