OSDN Git Service

manifest list mg
[pettanr/pettanr.git] / app / models / sheet_panel.rb
1 class SheetPanel < Peta::Content
2   belongs_to :author
3   belongs_to :panel
4   belongs_to :sheet
5   accepts_nested_attributes_for :panel, :allow_destroy => true
6   
7   validates :sheet_id, :numericality => {:allow_blank => true}
8   validates :panel_id, :numericality => {:allow_blank => true}
9   validates :author_id, :presence => true, :numericality => true, :existence => {:both => false}
10   validates :x, :presence => true, :numericality => true
11   validates :y, :presence => true, :numericality => true
12   validates :z, :presence => true, :numericality => {:greater_than => 0}
13   validates :t, :presence => true, :numericality => {:greater_than_or_equal_to => 0}
14   
15   def self.owner_model
16     Sheet
17   end
18   
19   def supply_default
20     self.x = 15
21     self.y = 15
22     if self.sheet
23       self.t = self.sheet.new_t 
24       self.z = self.sheet.new_z 
25     else
26       self.sheet_id = nil
27       self.panel_id = nil
28       self.z = 1
29       self.t = nil
30     end
31   end
32   
33   def overwrite operators
34     return false unless operators.author
35     self.author_id = operators.author.id
36   end
37   
38   def visible? operators
39     return false unless super
40     self.owner_model.visible? operators
41   end
42   
43   def self.list_where
44     'sheets.visible > 0'
45   end
46   
47   def self.list_order
48     'sheet_panels.updated_at desc'
49   end
50   
51   def self.play_list_where cid
52     ['sheet_panels.sheet_id = ?', cid]
53   end
54   
55   def self.play_list sheet, author
56     SheetPanel.where(self.play_list_where(sheet.id)).includes(SheetPanel.list_opt).order('sheet_panels.t')
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 boost operators
162     if self.panel
163       self.panel.author_id = operators.author.id
164       self.panel.panel_elements.each do |elm|
165         elm.new_panel = self
166         elm.boost
167       end
168     end
169   end
170   
171   def panel_attributes
172     if self.panel
173       {'panel_attributes' => self.panel.copy}
174     else
175       {}
176     end
177   end
178   
179   def self.new_t sheet_id
180     r = SheetPanel.max_t(sheet_id)
181     r.blank? ? 0 : r.to_i + 1
182   end
183   
184   def self.max_t sheet_id
185     SheetPanel.maximum(:t, :conditions => ['sheet_id = ?', sheet_id])
186   end
187   
188   def self.find_t sheet_id, t
189     SheetPanel.find(:first, :conditions => ['sheet_id = ? and t = ?', sheet_id, t])
190   end
191   
192   def self.collect_t sheet_panel
193     r = SheetPanel.find(:all, :conditions => ['sheet_id = ?', sheet_panel.sheet_id], :order => 't')
194     r.map {|sp| sp.t}
195   end
196   
197   def self.serial? ary
198     i = 0
199     ary.compact.sort.each do |t|
200       break false unless t == i
201       i += 1
202     end
203     ary.compact.size == i
204   end
205   
206   def self.validate_t sheet_panel
207     SheetPanel.serial?(SheetPanel.collect_t(sheet_panel))
208   end
209   
210   def insert_shift
211     SheetPanel.update_all('t = t + 1', ['sheet_id = ? and t >= ?', self.sheet_id, self.t])
212   end
213   
214   def lesser_shift old_t
215     self.t = 0 if self.t < 0
216     SheetPanel.update_all('t = t + 1', ['sheet_id = ? and (t >= ? and t < ?)', self.sheet_id, self.t, old_t])
217   end
218   
219   def higher_shift old_t
220     nf = SheetPanel.find_t(self.sheet_id, self.t)
221     max_t = SheetPanel.max_t(self.sheet_id).to_i
222     self.t = max_t if self.t > max_t
223     SheetPanel.update_all('t = t - 1', ['sheet_id = ? and (t > ? and t <= ?)', self.sheet_id, old_t, self.t])
224   end
225   
226   def update_shift old_t
227     if self.t > old_t
228       higher_shift old_t
229     else
230       lesser_shift old_t
231     end
232   end
233   
234   def rotate old_t = nil
235     if self.new_record?
236       if self.t.blank?
237         self.t = SheetPanel.new_t self.sheet_id
238       else
239         self.insert_shift
240       end
241     else
242       if self.t.blank?
243       else
244         self.update_shift old_t
245       end
246     end
247   end
248   
249   def allow? operators
250     return nil if self.sheet_id == nil or self.panel_id == nil
251     self.sheet.own?(operators) and self.panel.usable?(operators)
252   end
253   
254   def store operators, old_t = nil
255     res = false
256     SheetPanel.transaction do
257       case self.allow? operators
258       when true
259         self.rotate old_t
260       when false
261         raise ActiveRecord::Forbidden
262       else
263       end
264       res = self.save
265       raise ActiveRecord::Rollback unless res
266       res = SheetPanel.validate_t(self) 
267       unless res
268         self.errors.add :t, 'unserialized'
269         raise ActiveRecord::Rollback 
270       end
271     end
272     res
273   end
274   
275   def destroy_and_shorten
276     res = false
277     SheetPanel.transaction do
278       SheetPanel.update_all('t = t - 1', ['sheet_id = ? and (t > ?)', self.sheet_id, self.t])
279       raise ActiveRecord::Rollback unless self.destroy
280       res = true
281     end
282     res
283   end
284   
285     # element.rb
286     def self.colum_structures
287       @@colum_structures ||= {
288       }
289     end
290     
291     def self.path_name with_engine = false
292       self.to_s.tableize
293     end
294     
295     def new_index
296       @new_index
297     end
298     
299     def new_index= v
300       @new_index = v
301     end
302     
303     def new_sheet
304       @new_sheet
305     end
306     
307     def new_sheet= v
308       @new_sheet = v
309     end
310     
311     def get_sheet
312       self.sheet || @new_sheet
313     end
314     
315     def tag_id c = nil
316       'sheet' + self.tag_sheet_id + self.tag_element_type + self.tag_element_id + c.to_s
317     end
318     
319     def field_tag_id f
320       self.tag_id + f.to_s
321     end
322     
323     def tag_sheet_id
324       (self.get_sheet == nil or self.get_sheet.new_record?) ? '0' : self.get_sheet.id.to_s
325     end
326     
327     def tag_element_id
328       self.new_record? ? '0' : self.id.to_s
329     end
330     
331     def tag_element_type
332       'sheet_panel'
333     end
334     
335     def tag_new_index
336       self.new_index.to_s
337     end
338     
339     def path_name with_engine = false
340       self.class.path_name(with_engine)
341     end
342     
343     def form_template with_engine = false
344       self.path_name(with_engine) + '/form'
345     end
346     
347     def scenario_template with_engine = false
348       self.path_name(with_engine) + '/scenario'
349     end
350     
351     def element_face_template with_engine = false
352       self.path_name(with_engine) + '/element_face'
353     end
354     
355     def form_helper_template(colum_name)
356       self.class.colum_structures[colum_name][:helper]
357     end
358     
359     def tag_attributes column = nil, opt = {}
360       {
361         :id => self.field_tag_id(column), :sheet_id => self.tag_sheet_id, 
362         :element_id => self.tag_element_id, :element_type => self.tag_element_type
363       }.merge(opt)
364     end
365     
366     def field_tag_attributes column, no_attr, opt = {}
367       self.tag_attributes(column).merge(
368         {:column => column, :new_index => self.tag_new_index, :no_attr => no_attr}
369       ).merge(opt)
370     end
371     
372     #render element by body
373     def any_tag_attributes name = nil, opt = {}
374       r = self.tag_attributes(name)
375       r.merge!(
376         {:new_index => self.tag_new_index}
377       ) if self.new_index
378       r.merge(opt)
379     end
380     
381     def select_tag_attributes(selected, column, no_attr)
382       [
383         :last, :first, 
384         {:html => {:selected => selected}}, 
385         self.field_tag_attributes(column, no_attr)
386       ]
387     end
388     
389     def tag_attr column = nil, opt = {}
390       self.tag_attributes(column, opt).to_attr
391     end
392     
393     def field_tag_attr column, no_attr, opt = {}
394       self.field_tag_attributes(column, no_attr, opt).to_attr
395     end
396     
397     def any_tag_attr name = nil, opt = {}
398       self.any_tag_attributes(name, opt).to_attr
399     end
400     
401 end