OSDN Git Service

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