OSDN Git Service

fix has one manifest
[pettanr/pettanr.git] / app / models / panel.rb
1 #コマ
2 class Panel < Peta::Content
3   belongs_to :author
4   has_many :scroll_panels
5   has_many :sheet_panels
6   has_many :panel_pictures, :dependent => :destroy
7   has_many :speech_balloons, :dependent => :destroy
8   has_many :ground_pictures, :dependent => :destroy
9   has_many :ground_colors, :dependent => :destroy
10   accepts_nested_attributes_for :panel_pictures, :allow_destroy => true
11   accepts_nested_attributes_for :speech_balloons, :allow_destroy => true
12   accepts_nested_attributes_for :ground_pictures, :allow_destroy => true
13   accepts_nested_attributes_for :ground_colors, :allow_destroy => true
14
15   validates :width, :presence => true, :numericality => true, :natural_number => true
16   validates :height, :presence => true, :numericality => true, :natural_number => true
17   validates :border, :presence => true, :numericality => {:greater_than_or_equal_to => 0}
18   validates :author_id, :presence => true, :numericality => true, :existence => {:both => false}
19   validates :publish, :presence => true, :numericality => true
20   
21   def self.valid_encode_columns
22     super + ['caption']
23   end
24   
25   def self.each_element_class_names
26     Manifest.manifest.system_resources.elements.each do |k, n|
27       yield k
28     end
29   end
30   
31   def self.class_name_to_class k
32     Object.const_get k
33   end
34   
35   def self.each_element_classes
36     self.each_element_class_names do |k|
37       e = self.class_name_to_class k
38       yield e
39     end
40   end
41   
42   def elements_by_class_name class_name
43     self.__send__ class_name.tableize
44   end
45   
46   def supply_default
47     self.border = 2
48     self.publish = 0
49   end
50   
51   def overwrite operators
52     return false unless operators.author
53     self.author_id = operators.author.id
54   end
55   
56   def visible? operators
57     return true if super
58     return true if self.new_record?
59     self.publish?
60   end
61   
62   def usable? operators
63     self.visible? operators
64   end
65   
66   def publish?
67     self.publish > 0
68   end
69   
70   def tag_id c = nil
71     'panel' + self.tag_panel_id + c.to_s
72   end
73   
74   def tag_panel_id
75     self.new_record? ? '0' : self.id.to_s
76   end
77   
78   def field_tag_id f
79     self.tag_id + f.to_s
80   end
81   
82   def tag_attributes column = nil, opt = {}
83     {
84       :id => self.field_tag_id(column), :panel_id => self.tag_panel_id
85     }.merge(opt)
86   end
87   
88   def select_tag_attributes(selected, column, opt = {})
89     [
90       {:html => {:selected => selected}}, 
91       self.field_tag_attributes(column, opt)
92     ]
93   end
94   
95   def field_tag_attributes column, no_attr, opt = {}
96     self.tag_attributes(column).merge(
97       {:column => column}
98     ).merge(opt)
99   end
100   
101   def tag_attr column = nil, opt = {}
102     self.tag_attributes(column, opt).to_attr
103   end
104   
105   def field_tag_attr column, no_attr, opt = {}
106     self.field_tag_attributes(column, no_attr, opt).to_attr
107   end
108   
109     def render_count
110       @render_count ||= 1
111     end
112     
113     def rendered
114       @render_count = render_count + 1
115     end
116     
117   def self.list_where
118     'panels.publish > 0'
119   end
120   
121   def self.list_order
122     'panels.updated_at desc'
123   end
124   
125   def self.list_opt
126     r = {
127       :author => {}
128     }
129     self.each_element_classes do |e|
130       r.merge!(e.list_opt_for_panel)
131     end
132     r
133   end
134   
135   def self.show_opt
136     r = {
137       :author => {}
138     }
139     self.each_element_classes do |e|
140       r.merge!(e.show_opt_for_panel)
141     end
142     {:include => r}
143   end
144   
145   def parts_element
146     r = []
147     self.class.each_element_class_names do |k|
148       r += (self.elements_by_class_name(k) || [])
149     end
150     r
151   end
152   
153   def zorderd_elements
154     res = []
155     self.parts_element.each do |e|
156       res[e.z-1] = e
157     end
158     res
159   end
160   
161   def panel_elements
162     res = []
163     self.parts_element.each do |e|
164       res[e.t] = e
165     end
166     res
167   end
168   
169   def elements
170     self.panel_elements.map {|e|
171       #(-_-;)<... kore wa hidoi
172       JSON.parse e.to_json({:include => e.class.json_opt_for_panel})
173     }
174   end
175   
176   def panel_elements_as_json
177     self.to_json({:include => {:author => {}}, :methods => :elements})
178   end
179   
180   def self.list_as_json_text ary
181     '[' + ary.map {|i| i.panel_elements_as_json }.join(',') + ']'
182   end
183   
184   def new_t
185     self.panel_elements.size
186   end
187   
188   def new_z
189     self.panel_elements.size + 1
190   end
191   
192   def scenario
193     panel_elements.map { |e|
194       e.scenario
195     }.join
196   end
197   
198   def plain_scenario
199     panel_elements.map { |e|
200       e.plain_scenario
201     }.join
202   end
203   
204   def licensed_pictures
205     r = {}
206     self.panel_elements.each do |elm|
207       next unless elm.class.has_picture?
208       r[elm.picture_id] = elm.picture unless r[elm.picture_id]
209     end
210     r
211   end
212   
213   def self.visible_count
214     Panel.count
215   end
216   
217   def self.collect_element_value elements, name
218     elements.map {|e|
219       e.map {|o|
220         if o['_destroy'] or o[:_destroy]
221           nil
222         else
223           o[name]
224         end
225       }.compact
226     }.flatten
227   end
228   
229   def self.validate_serial ary, offset = 0
230     i = offset
231     ary.compact.sort.each do |n|
232       break false unless n == i
233       i += 1
234     end
235     ary.compact.size == i - offset
236   end
237   
238   def self.validate_element_serial elements, name, offset = 0
239     Panel.validate_serial(Panel.collect_element_value(elements, name), offset)
240   end
241   
242   def self.validate_elements_serial c
243     c.map {|conf|
244       Panel.validate_element_serial(conf[:elements], conf[:name], conf[:offset]) ? nil : false
245     }.compact.empty?
246   end
247   
248   def validate_serial_list
249     l = []
250     self.class.each_element_class_names do |k|
251       l << self.elements_by_class_name(k)
252     end
253     [
254       {:elements => l, :name => :t, :offset => 0}, 
255       {:elements => l, :name => :z, :offset => 1}
256     ]
257   end
258   def validate_child
259 #    r1 = Panel.validate_elements_id validate_id_list
260     Panel.validate_elements_serial validate_serial_list
261   end
262   
263   def boost
264     @new_element_index = 0
265     self.panel_elements.each do |elm|
266       if elm.new_record?
267         elm.new_index = @new_element_index
268         @new_element_index += 1
269       end
270     end
271   end 
272   
273   def store attr, operators
274     if attr == false
275       self.errors.add :base, I18n.t('errors.invalid_json')
276       return false
277     end
278     self.attributes = attr
279     self.overwrite operators
280     res = false
281     Panel.transaction do
282       self.panel_elements.each do |elm|
283         elm.new_panel = self
284         elm.boost
285       end
286 #self.publish = nil
287       res = self.save
288       unless validate_child
289         res = false
290         self.errors.add :base, I18n.t('errors.invalid_t')
291         raise ActiveRecord::Rollback
292       end
293     end
294     res
295   end
296   
297   def remove_element target, operators
298     ct = target.t
299     cz = target.z
300     panel_attributes = {}
301     self.panel_elements.each do |elm|
302       attr = elm.attributes
303       if elm == target
304         attr['_destroy'] = true
305       end
306       if elm.t > ct
307         attr['t']  -= 1 
308       end
309       if elm.z > cz
310         attr['z']  -= 1 
311       end
312       panel_attributes[elm.class.to_s.tableize + '_attributes'] ||= {}
313       panel_attributes[elm.class.to_s.tableize + '_attributes'][elm.id] = attr
314     end
315     self.store(panel_attributes, operators)
316   end
317   
318   def destroy_with_elements
319     res = false
320     Panel.transaction do
321       self.parts_element.each do |element|
322         raise ActiveRecord::Rollback unless element.destroy
323       end
324       raise ActiveRecord::Rollback unless self.destroy
325       res = true
326     end
327     res
328   end
329   
330   def copy
331     attr = self.copy_attributes
332     Panel.each_element_class_names do |n|
333       attr.merge! Panel.class_name_to_class(n).panelize(self.elements_by_class_name(n).map {|elm|  elm.copy_attributes})
334     end
335     attr
336   end
337   
338   def copy_attributes
339     r = self.attributes
340     r.delete 'id'
341     r.delete 'author_id'
342     r.delete 'created_at'
343     r.delete 'updated_at'
344     r
345   end
346   
347   def self.panelize panel
348     attr = panel.attributes
349     attr.delete 'id'
350     attr
351   end
352   
353   
354 =begin
355   def self.validate_id ary, pid
356     ary.map {|v|
357       if pid
358         (v == pid or v == nil) ? nil : false
359       else
360         v ? false : nil
361       end
362     }.compact.empty?
363   end
364   
365   def self.validate_element_id elements, name, pid
366     Panel.validate_id(Panel.collect_element_value(elements, name), pid)
367   end
368   
369   def self.validate_elements_id c
370     c.map {|conf|
371       Panel.validate_element_id(conf[:elements], conf[:name], conf[:parent_id]) ? nil : false
372     }.compact.empty?
373   end
374   
375   def validate_id_list
376     r = self.speech_balloons.map {|sb|
377       {:elements => [sb.speeches, sb.balloons], :name => :speech_balloon_id, :parent_id => sb.id}
378     }
379     r.unshift({:elements => [self.panel_pictures, self.speech_balloons], :name => :panel_id, :parent_id => self.id})
380     r
381   end
382 =end
383   
384 end