OSDN Git Service

ee85e6f0fbe702ad3b1c4cd6b282a7009fc81100
[pettanr/pettanr.git] / app / models / sheet.rb
1 class Sheet < Peta::Content
2   load_manifest
3   has_many :sheet_panels
4   has_many :story_sheets
5   belongs_to :author
6   
7   validates :caption, :presence => true, :length => {:maximum => 100}
8   validates :width, :presence => true, :numericality => true, :natural_number => true
9   validates :height, :presence => true, :numericality => true, :natural_number => true
10   validates :visible, :presence => true, :numericality => true, :inclusion => {:in => 0..1}
11   accepts_nested_attributes_for :sheet_panels, :allow_destroy => true
12   
13   def self.each_element_class_names
14     {'SheetPanel' => 'sheet_panels'}.each do |k, n|
15       yield k
16     end
17   end
18   
19   def self.class_name_to_class k
20     Object.const_get k
21   end
22   
23   def self.each_element_classes
24     self.each_element_class_names do |k|
25       e = self.class_name_to_class k
26       yield e
27     end
28   end
29   
30   def elements_by_class_name class_name
31     self.__send__ class_name.tableize
32   end
33   
34   def supply_default
35     self.visible = 0 if self.visible.blank?
36   end
37   
38   def overwrite operators
39     return false unless operators.author
40     self.author_id = operators.author.id
41   end
42   
43   def visible? operators
44     return false unless super
45     return true if self.new_record?
46     self.visible > 0
47   end
48   
49   def usable? operators
50     self.visible? operators
51   end
52   
53   def symbol_filename
54   end
55   
56   def tag_id
57     'sheet' + self.tag_sheet_id
58   end
59   
60   def tag_sheet_id
61     self.new_record? ? '0' : self.id.to_s
62   end
63   
64   def field_tag_id f
65     self.tag_id + f.to_s
66   end
67   
68   def self.list_where
69     'sheets.visible > 0'
70   end
71   
72   def self.list_order
73     'sheets.updated_at desc'
74   end
75   
76   def self.list_opt
77     {:sheet_panels => {:panel => {}}, :author => {} }
78   end
79   
80   def self.list_json_opt
81     {:include => {:sheet_panels => {:include => {:panel => {}}}, :author => {}}}
82   end
83   
84   def self.show_opt
85     {:include => {:sheet_panels => {:panel => {}}, :author => {}}}
86   end
87   
88   def self.show_json_opt
89     {:include => {:sheet_panels => {:include => {:panel => {}}}, :author => {}}}
90   end
91   
92   def parts_element
93     r = []
94     self.class.each_element_class_names do |k|
95       r += (self.elements_by_class_name(k) || [])
96     end
97     r
98   end
99   
100   def zorderd_elements
101     res = []
102     self.parts_element.each do |e|
103       res[e.z-1] = e
104     end
105     res
106   end
107   
108   def sheet_elements
109     res = []
110     self.parts_element.each do |e|
111       res[e.t] = e
112     end
113     res
114   end
115   
116   def new_t
117     self.sheet_elements.size
118   end
119   
120   def new_z
121     self.sheet_elements.size + 1
122   end
123   
124   def self.visible_count
125     Sheet.count 'visible > 0'
126   end
127   
128   def self.collect_element_value elements, name
129     elements.map {|e|
130       e.map {|o|
131         if o['_destroy'] or o[:_destroy]
132           nil
133         else
134           o[name]
135         end
136       }.compact
137     }.flatten
138   end
139   
140   def self.validate_serial ary, offset = 0
141     i = offset
142     ary.compact.sort.each do |n|
143       break false unless n == i
144       i += 1
145     end
146     ary.compact.size == i - offset
147   end
148   
149   def self.validate_element_serial elements, name, offset = 0
150     Sheet.validate_serial(Sheet.collect_element_value(elements, name), offset)
151   end
152   
153   def self.validate_elements_serial c
154     c.map {|conf|
155       Sheet.validate_element_serial(conf[:elements], conf[:name], conf[:offset]) ? nil : false
156     }.compact.empty?
157   end
158   
159   def validate_serial_list
160     l = []
161     self.class.each_element_class_names do |k|
162       l << self.elements_by_class_name(k)
163     end
164 #    l = [self.sheet_panels]
165     [
166       {:elements => l, :name => :t, :offset => 0}, 
167       {:elements => l, :name => :z, :offset => 1}
168     ]
169   end
170   
171   def validate_child
172 #    r1 = Panel.validate_elements_id validate_id_list
173     Sheet.validate_elements_serial validate_serial_list
174   end
175   
176   def boost
177     @new_element_index = 0
178     self.panel_elements.each do |elm|
179       if elm.new_record?
180         elm.new_index = @new_element_index
181         @new_element_index += 1
182       end
183     end
184   end 
185   
186   def store attr, operators
187     if attr == false
188       self.errors.add :base, I18n.t('errors.invalid_json')
189       return false
190     end
191     self.attributes = attr
192     self.overwrite operators
193     res = false
194     Sheet.transaction do
195       self.sheet_elements.each do |elm|
196         elm.new_sheet = self
197         elm.boost operators
198       end
199       res = self.save
200       unless validate_child
201         res = false
202         self.errors.add :base, I18n.t('errors.invalid_t')
203         raise ActiveRecord::Rollback
204       end
205     end
206     res
207   end
208   
209   def destroy_with_sheet_panel
210     res = false
211     Sheet.transaction do
212       self.sheet_panels.each do |sheet_panel|
213         raise ActiveRecord::Rollback unless sheet_panel.destroy
214       end
215       raise ActiveRecord::Rollback unless self.destroy
216       res = true
217     end
218     res
219   end
220   
221   def scenario
222     panels.map {|panel|
223       panel.scenario
224     }.join
225   end
226   
227   def plain_scenario
228     panels.map {|panel|
229       panel.plain_scenario
230     }.join
231   end
232   
233   def licensed_pictures
234     r = {}
235     self.sheet_elements.each do |elm|
236       r.merge!(elm.licensed_pictures)
237     end
238     r
239   end
240   
241   def copyable?
242     r = true
243     Sheet.each_element_class_names do |n|
244       self.elements_by_class_name(n).each do |elm|
245         next if elm.copyable?
246         r = false
247         break
248       end
249       break unless r
250     end
251     r
252   end
253   
254   def copy
255     attr = self.copy_attributes
256     Sheet.each_element_class_names do |n|
257       element_attr = Sheet.class_name_to_class(n).panelize(
258         self.elements_by_class_name(n).map {|elm|
259           elm.copy_attributes.merge elm.panel_attributes
260         }
261       )
262       attr.merge! element_attr
263     end
264     attr
265   end
266   
267   def copy_attributes
268     r = self.attributes
269     r.delete 'id'
270     r.delete 'author_id'
271     r.delete 'created_at'
272     r.delete 'updated_at'
273     r
274   end
275   
276   def self.panelize sheet
277     attr = sheet.attributes
278     attr.delete 'id'
279     attr
280   end
281   
282 end