OSDN Git Service

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