OSDN Git Service

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