OSDN Git Service

work
[pettanr/pettanr.git] / app / models / panel.rb
1 #コマ
2 class Panel < Pettanr::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     Pettanr::Application.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       :last, :first, 
91       {:html => {:selected => selected}}, 
92       self.field_tag_attributes(column, opt)
93     ]
94   end
95   
96   def field_tag_attributes column, opt = {}
97     self.tag_attributes(column).merge(
98       {:column => column}
99     ).merge(opt)
100   end
101   
102   def tag_attr column = nil, opt = {}
103     self.tag_attributes(column, opt).to_attr
104   end
105   
106   def field_tag_attr column, no_attr, opt = {}
107     self.field_tag_attributes(column, no_attr, opt).to_attr
108   end
109   
110     def render_count
111       @render_count ||= 1
112     end
113     
114     def rendered
115       @render_count = render_count + 1
116     end
117     
118   def self.list_where
119     'panels.publish > 0'
120   end
121   
122   def self.list_order
123     'panels.updated_at desc'
124   end
125   
126   def self.list_opt
127     r = {
128       :author => {}
129     }
130     self.each_element_classes do |e|
131       r.merge!(e.list_opt_for_panel)
132     end
133     r
134   end
135   
136   def self.show_opt
137     r = {
138       :author => {}
139     }
140     self.each_element_classes do |e|
141       r.merge!(e.show_opt_for_panel)
142     end
143     {:include => r}
144   end
145   
146   def parts_element
147     r = []
148     self.class.each_element_class_names do |k|
149       r += (self.elements_by_class_name(k) || [])
150     end
151     r
152   end
153   
154   def zorderd_elements
155     res = []
156     self.parts_element.each do |e|
157       res[e.z-1] = e
158     end
159     res
160   end
161   
162   def panel_elements
163     res = []
164     self.parts_element.each do |e|
165       res[e.t] = e
166     end
167     res
168   end
169   
170   def elements
171     self.panel_elements.map {|e|
172       #(-_-;)<... kore wa hidoi
173       JSON.parse e.to_json({:include => e.class.json_opt_for_panel})
174     }
175   end
176   
177   def panel_elements_as_json
178     self.to_json({:include => {:author => {}}, :methods => :elements})
179   end
180   
181   def self.list_as_json_text ary
182     '[' + ary.map {|i| i.panel_elements_as_json }.join(',') + ']'
183   end
184   
185   def new_t
186     self.panel_elements.size
187   end
188   
189   def new_z
190     self.panel_elements.size + 1
191   end
192   
193   def scenario
194     panel_elements.map { |e|
195       e.scenario
196     }.join
197   end
198   
199   def plain_scenario
200     panel_elements.map { |e|
201       e.plain_scenario
202     }.join
203   end
204   
205   def licensed_pictures
206     r = {}
207     self.panel_elements.each do |elm|
208       next unless elm.class.has_picture?
209       r[elm.picture_id] = elm.picture unless r[elm.picture_id]
210     end
211     r
212   end
213   
214   def self.visible_count
215     Panel.count
216   end
217   
218   def self.collect_element_value elements, name
219     elements.map {|e|
220       e.map {|o|
221         if o['_destroy'] or o[:_destroy]
222           nil
223         else
224           o[name]
225         end
226       }.compact
227     }.flatten
228   end
229   
230   def self.validate_serial ary, offset = 0
231     i = offset
232     ary.compact.sort.each do |n|
233       break false unless n == i
234       i += 1
235     end
236     ary.compact.size == i - offset
237   end
238   
239   def self.validate_element_serial elements, name, offset = 0
240     Panel.validate_serial(Panel.collect_element_value(elements, name), offset)
241   end
242   
243   def self.validate_elements_serial c
244     c.map {|conf|
245       Panel.validate_element_serial(conf[:elements], conf[:name], conf[:offset]) ? nil : false
246     }.compact.empty?
247   end
248   
249   def validate_serial_list
250     l = []
251     self.class.each_element_class_names do |k|
252       l << self.elements_by_class_name(k)
253     end
254     [
255       {:elements => l, :name => :t, :offset => 0}, 
256       {:elements => l, :name => :z, :offset => 1}
257     ]
258   end
259   def validate_child
260 #    r1 = Panel.validate_elements_id validate_id_list
261     Panel.validate_elements_serial validate_serial_list
262   end
263   
264   def boost
265     @new_element_index = 0
266     self.panel_elements.each do |elm|
267       if elm.new_record?
268         elm.new_index = @new_element_index
269         @new_element_index += 1
270       end
271     end
272   end 
273   
274   def store attr, operators
275     if attr == false
276       self.errors.add :base, I18n.t('errors.invalid_json')
277       return false
278     end
279     self.attributes = attr
280     self.overwrite operators
281     res = false
282     Panel.transaction do
283       self.panel_elements.each do |elm|
284         elm.new_panel = self
285         elm.boost
286       end
287 #self.publish = nil
288       res = self.save
289       unless validate_child
290         res = false
291         self.errors.add :base, I18n.t('errors.invalid_t')
292         raise ActiveRecord::Rollback
293       end
294     end
295     res
296   end
297   
298   def remove_element target, operators
299     ct = target.t
300     cz = target.z
301     panel_attributes = {}
302     self.panel_elements.each do |elm|
303       attr = elm.attributes
304       if elm == target
305         attr['_destroy'] = true
306       end
307       if elm.t > ct
308         attr['t']  -= 1 
309       end
310       if elm.z > cz
311         attr['z']  -= 1 
312       end
313       panel_attributes[elm.class.to_s.tableize + '_attributes'] ||= {}
314       panel_attributes[elm.class.to_s.tableize + '_attributes'][elm.id] = attr
315     end
316     self.store(panel_attributes, operators)
317   end
318   
319   def destroy_with_elements
320     res = false
321     Panel.transaction do
322       self.parts_element.each do |element|
323         raise ActiveRecord::Rollback unless element.destroy
324       end
325       raise ActiveRecord::Rollback unless self.destroy
326       res = true
327     end
328     res
329   end
330   
331   def copy
332     attr = self.copy_attributes
333     Panel.each_element_class_names do |n|
334       attr.merge! Panel.class_name_to_class(n).panelize(self.elements_by_class_name(n).map {|elm|  elm.copy_attributes})
335     end
336     attr
337   end
338   
339   def copy_attributes
340     r = self.attributes
341     r.delete 'id'
342     r.delete 'author_id'
343     r.delete 'created_at'
344     r.delete 'updated_at'
345     r
346   end
347   
348   def self.panelize panel
349     attr = panel.attributes
350     attr.delete 'id'
351     attr
352   end
353   
354   
355 =begin
356   def self.validate_id ary, pid
357     ary.map {|v|
358       if pid
359         (v == pid or v == nil) ? nil : false
360       else
361         v ? false : nil
362       end
363     }.compact.empty?
364   end
365   
366   def self.validate_element_id elements, name, pid
367     Panel.validate_id(Panel.collect_element_value(elements, name), pid)
368   end
369   
370   def self.validate_elements_id c
371     c.map {|conf|
372       Panel.validate_element_id(conf[:elements], conf[:name], conf[:parent_id]) ? nil : false
373     }.compact.empty?
374   end
375   
376   def validate_id_list
377     r = self.speech_balloons.map {|sb|
378       {:elements => [sb.speeches, sb.balloons], :name => :speech_balloon_id, :parent_id => sb.id}
379     }
380     r.unshift({:elements => [self.panel_pictures, self.speech_balloons], :name => :panel_id, :parent_id => self.id})
381     r
382   end
383 =end
384   
385 end