OSDN Git Service

element
[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 boost operators
159     if self.panel
160       self.panel.author_id = operators.author.id
161       self.panel.panel_elements.each do |elm|
162         elm.new_panel = self
163         elm.boost
164       end
165     end
166   end
167   
168   def panel_attributes
169     if self.panel
170       {'panel_attributes' => self.panel.copy}
171     else
172       {}
173     end
174   end
175   
176   def self.new_t sheet_id
177     r = SheetPanel.max_t(sheet_id)
178     r.blank? ? 0 : r.to_i + 1
179   end
180   
181   def self.max_t sheet_id
182     SheetPanel.maximum(:t, :conditions => ['sheet_id = ?', sheet_id])
183   end
184   
185   def self.find_t sheet_id, t
186     SheetPanel.find(:first, :conditions => ['sheet_id = ? and t = ?', sheet_id, t])
187   end
188   
189   def self.collect_t sheet_panel
190     r = SheetPanel.find(:all, :conditions => ['sheet_id = ?', sheet_panel.sheet_id], :order => 't')
191     r.map {|sp| sp.t}
192   end
193   
194   def self.serial? ary
195     i = 0
196     ary.compact.sort.each do |t|
197       break false unless t == i
198       i += 1
199     end
200     ary.compact.size == i
201   end
202   
203   def self.validate_t sheet_panel
204     SheetPanel.serial?(SheetPanel.collect_t(sheet_panel))
205   end
206   
207   def insert_shift
208     SheetPanel.update_all('t = t + 1', ['sheet_id = ? and t >= ?', self.sheet_id, self.t])
209   end
210   
211   def lesser_shift old_t
212     self.t = 0 if self.t < 0
213     SheetPanel.update_all('t = t + 1', ['sheet_id = ? and (t >= ? and t < ?)', self.sheet_id, self.t, old_t])
214   end
215   
216   def higher_shift old_t
217     nf = SheetPanel.find_t(self.sheet_id, self.t)
218     max_t = SheetPanel.max_t(self.sheet_id).to_i
219     self.t = max_t if self.t > max_t
220     SheetPanel.update_all('t = t - 1', ['sheet_id = ? and (t > ? and t <= ?)', self.sheet_id, old_t, self.t])
221   end
222   
223   def update_shift old_t
224     if self.t > old_t
225       higher_shift old_t
226     else
227       lesser_shift old_t
228     end
229   end
230   
231   def rotate old_t = nil
232     if self.new_record?
233       if self.t.blank?
234         self.t = SheetPanel.new_t self.sheet_id
235       else
236         self.insert_shift
237       end
238     else
239       if self.t.blank?
240       else
241         self.update_shift old_t
242       end
243     end
244   end
245   
246   def allow? operators
247     return nil if self.sheet_id == nil or self.panel_id == nil
248     self.sheet.own?(operators) and self.panel.usable?(operators)
249   end
250   
251   def store operators, old_t = nil
252     res = false
253     SheetPanel.transaction do
254       case self.allow? operators
255       when true
256         self.rotate old_t
257       when false
258         raise ActiveRecord::Forbidden
259       else
260       end
261       res = self.save
262       raise ActiveRecord::Rollback unless res
263       res = SheetPanel.validate_t(self) 
264       unless res
265         self.errors.add :t, 'unserialized'
266         raise ActiveRecord::Rollback 
267       end
268     end
269     res
270   end
271   
272   def destroy_and_shorten
273     res = false
274     SheetPanel.transaction do
275       SheetPanel.update_all('t = t - 1', ['sheet_id = ? and (t > ?)', self.sheet_id, self.t])
276       raise ActiveRecord::Rollback unless self.destroy
277       res = true
278     end
279     res
280   end
281   
282     # element.rb
283     def self.colum_structures
284       @@colum_structures ||= {
285       }
286     end
287     
288     def self.path_name with_engine = false
289       self.to_s.tableize
290     end
291     
292     def new_index
293       @new_index
294     end
295     
296     def new_index= v
297       @new_index = v
298     end
299     
300     def new_sheet
301       @new_sheet
302     end
303     
304     def new_sheet= v
305       @new_sheet = v
306     end
307     
308     def get_sheet
309       self.sheet || @new_sheet
310     end
311     
312     def tag_id c = nil
313       'sheet' + self.tag_sheet_id + self.tag_element_type + self.tag_element_id + c.to_s
314     end
315     
316     def field_tag_id f
317       self.tag_id + f.to_s
318     end
319     
320     def tag_sheet_id
321       (self.get_sheet == nil or self.get_sheet.new_record?) ? '0' : self.get_sheet.id.to_s
322     end
323     
324     def tag_element_id
325       self.new_record? ? '0' : self.id.to_s
326     end
327     
328     def tag_element_type
329       'sheet_panel'
330     end
331     
332     def tag_new_index
333       self.new_index.to_s
334     end
335     
336     def path_name with_engine = false
337       self.class.path_name(with_engine)
338     end
339     
340     def form_template with_engine = false
341       self.path_name(with_engine) + '/form'
342     end
343     
344     def scenario_template with_engine = false
345       self.path_name(with_engine) + '/scenario'
346     end
347     
348     def element_face_template with_engine = false
349       self.path_name(with_engine) + '/element_face'
350     end
351     
352     def form_helper_template(colum_name)
353       self.class.colum_structures[colum_name][:helper]
354     end
355     
356     def tag_attributes column = nil, opt = {}
357       {
358         :id => self.field_tag_id(column), :sheet_id => self.tag_sheet_id, 
359         :element_id => self.tag_element_id, :element_type => self.tag_element_type
360       }.merge(opt)
361     end
362     
363     def field_tag_attributes column, no_attr, opt = {}
364       self.tag_attributes(column).merge(
365         {:column => column, :new_index => self.tag_new_index, :no_attr => no_attr}
366       ).merge(opt)
367     end
368     
369     #render element by body
370     def any_tag_attributes name = nil, opt = {}
371       r = self.tag_attributes(name)
372       r.merge!(
373         {:new_index => self.tag_new_index}
374       ) if self.new_index
375       r.merge(opt)
376     end
377     
378     def select_tag_attributes(selected, column, no_attr)
379       [
380         :last, :first, 
381         {:html => {:selected => selected}}, 
382         self.field_tag_attributes(column, no_attr)
383       ]
384     end
385     
386     def tag_attr column = nil, opt = {}
387       self.tag_attributes(column, opt).to_attr
388     end
389     
390     def field_tag_attr column, no_attr, opt = {}
391       self.field_tag_attributes(column, no_attr, opt).to_attr
392     end
393     
394     def any_tag_attr name = nil, opt = {}
395       self.any_tag_attributes(name, opt).to_attr
396     end
397     
398 end