OSDN Git Service

Merge branch 'v06' of git.sourceforge.jp:/gitroot/pettanr/pettanr into v06
[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       if e['_destroy'] or e[:_destroy]
166         nil
167       else
168         e[name]
169       end
170     }
171   end
172   
173   def self.validate_serial ary, offset = 0
174     i = offset
175     ary.compact.sort.each do |n|
176       break false unless n == i
177       i += 1
178     end
179     ary.compact.size == i - offset
180   end
181   
182   def self.validate_element_serial elements, name, offset = 0
183     Panel.validate_serial(Panel.collect_element_value(elements, name), offset)
184   end
185   
186   def self.validate_elements_serial c
187     c.map {|conf|
188       Panel.validate_element_serial(conf[:elements], conf[:name], conf[:offset]) ? nil : false
189     }.compact.empty?
190   end
191   
192   def validate_serial_list
193     [
194       {:elements => self.elements_items, :name => :t, :offset => 0}, 
195       {:elements => self.elements_items, :name => :z, :offset => 1}
196     ]
197   end
198   def validate_child
199 #    r1 = Panel.validate_elements_id validate_id_list
200     Panel.validate_elements_serial validate_serial_list
201   end
202   
203   def store attr, operators
204     if attr == false
205       self.errors.add :base, I18n.t('errors.invalid_json')
206       return false
207     end
208     self.attributes = attr
209     self.overwrite operators
210     res = false
211     Panel.transaction do
212       self.boosts 'post'
213 #self.publish = nil
214       res = self.save
215       unless validate_child
216         res = false
217         self.errors.add :base, I18n.t('errors.invalid_t')
218         raise ActiveRecord::Rollback
219       end
220     end
221     res
222   end
223   
224   def remove_element target, operators
225     ct = target.t
226     cz = target.z
227     panel_attributes = {}
228     self.panel_elements.each do |elm|
229       attr = elm.attributes
230       if elm == target
231         attr['_destroy'] = true
232       end
233       if elm.t > ct
234         attr['t']  -= 1 
235       end
236       if elm.z > cz
237         attr['z']  -= 1 
238       end
239       panel_attributes[elm.class.to_s.tableize + '_attributes'] ||= {}
240       panel_attributes[elm.class.to_s.tableize + '_attributes'][elm.id] = attr
241     end
242     self.store(panel_attributes, operators)
243   end
244   
245   def destroy_with_elements
246     res = false
247     Panel.transaction do
248       self.parts_element.each do |element|
249         raise ActiveRecord::Rollback unless element.destroy
250       end
251       raise ActiveRecord::Rollback unless self.destroy
252       res = true
253     end
254     res
255   end
256   
257   def self.panelize panel
258     attr = panel.attributes
259     attr.delete 'id'
260     attr
261   end
262   
263   
264 =begin
265   def self.validate_id ary, pid
266     ary.map {|v|
267       if pid
268         (v == pid or v == nil) ? nil : false
269       else
270         v ? false : nil
271       end
272     }.compact.empty?
273   end
274   
275   def self.validate_element_id elements, name, pid
276     Panel.validate_id(Panel.collect_element_value(elements, name), pid)
277   end
278   
279   def self.validate_elements_id c
280     c.map {|conf|
281       Panel.validate_element_id(conf[:elements], conf[:name], conf[:parent_id]) ? nil : false
282     }.compact.empty?
283   end
284   
285   def validate_id_list
286     r = self.speech_balloons.map {|sb|
287       {:elements => [sb.speeches, sb.balloons], :name => :speech_balloon_id, :parent_id => sb.id}
288     }
289     r.unshift({:elements => [self.panel_pictures, self.speech_balloons], :name => :panel_id, :parent_id => self.id})
290     r
291   end
292 =end
293   
294 end