OSDN Git Service

add binder
[pettanr/pettanr.git] / app / models / sheet.rb
1 class Sheet < Peta::Root
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 self.list_where
57     'sheets.visible > 0'
58   end
59   
60   def self.list_order
61     'sheets.updated_at desc'
62   end
63   
64   def self.list_opt
65     {:sheet_panels => {:panel => {}}, :author => {} }
66   end
67   
68   def self.list_json_opt
69     {:include => {:sheet_panels => {:include => {:panel => {}}}, :author => {}}}
70   end
71   
72   def self.show_opt
73     {:include => {:sheet_panels => {:panel => {}}, :author => {}}}
74   end
75   
76   def self.show_json_opt
77     {:include => {:sheet_panels => {:include => {:panel => {}}}, :author => {}}}
78   end
79   
80   def parts_element
81     r = []
82     self.class.each_element_class_names do |k|
83       r += (self.elements_by_class_name(k) || [])
84     end
85     r
86   end
87   
88   def zorderd_elements
89     res = []
90     self.parts_element.each do |e|
91       res[e.z-1] = e
92     end
93     res
94   end
95   
96   def sheet_elements
97     res = []
98     self.parts_element.each do |e|
99       res[e.t] = e
100     end
101     res
102   end
103   
104   def new_t
105     self.sheet_elements.size
106   end
107   
108   def new_z
109     self.sheet_elements.size + 1
110   end
111   
112   def self.visible_count
113     Sheet.count 'visible > 0'
114   end
115   
116   def self.collect_element_value elements, name
117     elements.map {|e|
118       e.map {|o|
119         if o['_destroy'] or o[:_destroy]
120           nil
121         else
122           o[name]
123         end
124       }.compact
125     }.flatten
126   end
127   
128   def self.validate_serial ary, offset = 0
129     i = offset
130     ary.compact.sort.each do |n|
131       break false unless n == i
132       i += 1
133     end
134     ary.compact.size == i - offset
135   end
136   
137   def self.validate_element_serial elements, name, offset = 0
138     Sheet.validate_serial(Sheet.collect_element_value(elements, name), offset)
139   end
140   
141   def self.validate_elements_serial c
142     c.map {|conf|
143       Sheet.validate_element_serial(conf[:elements], conf[:name], conf[:offset]) ? nil : false
144     }.compact.empty?
145   end
146   
147   def validate_serial_list
148     l = []
149     self.class.each_element_class_names do |k|
150       l << self.elements_by_class_name(k)
151     end
152 #    l = [self.sheet_panels]
153     [
154       {:elements => l, :name => :t, :offset => 0}, 
155       {:elements => l, :name => :z, :offset => 1}
156     ]
157   end
158   
159   def validate_child
160 #    r1 = Panel.validate_elements_id validate_id_list
161     Sheet.validate_elements_serial validate_serial_list
162   end
163   
164   def store attr, operators
165     if attr == false
166       self.errors.add :base, I18n.t('errors.invalid_json')
167       return false
168     end
169     self.attributes = attr
170     self.overwrite operators
171     res = false
172     Sheet.transaction do
173       self.sheet_elements.each do |elm|
174         elm.new_sheet = self
175         elm.boost operators
176       end
177       res = self.save
178       unless validate_child
179         res = false
180         self.errors.add :base, I18n.t('errors.invalid_t')
181         raise ActiveRecord::Rollback
182       end
183     end
184     res
185   end
186   
187   def destroy_with_sheet_panel
188     res = false
189     Sheet.transaction do
190       self.sheet_panels.each do |sheet_panel|
191         raise ActiveRecord::Rollback unless sheet_panel.destroy
192       end
193       raise ActiveRecord::Rollback unless self.destroy
194       res = true
195     end
196     res
197   end
198   
199   def scenario
200     panels.map {|panel|
201       panel.scenario
202     }.join
203   end
204   
205   def plain_scenario
206     panels.map {|panel|
207       panel.plain_scenario
208     }.join
209   end
210   
211   def licensed_pictures
212     r = {}
213     self.sheet_elements.each do |elm|
214       r.merge!(elm.licensed_pictures)
215     end
216     r
217   end
218   
219   def copyable?
220     r = true
221     Sheet.each_element_class_names do |n|
222       self.elements_by_class_name(n).each do |elm|
223         next if elm.copyable?
224         r = false
225         break
226       end
227       break unless r
228     end
229     r
230   end
231   
232   def copy
233     attr = self.copy_attributes
234     Sheet.each_element_class_names do |n|
235       element_attr = Sheet.class_name_to_class(n).panelize(
236         self.elements_by_class_name(n).map {|elm|
237           elm.copy_attributes.merge elm.panel_attributes
238         }
239       )
240       attr.merge! element_attr
241     end
242     attr
243   end
244   
245   def copy_attributes
246     r = self.attributes
247     r.delete 'id'
248     r.delete 'author_id'
249     r.delete 'created_at'
250     r.delete 'updated_at'
251     r
252   end
253   
254   def self.panelize sheet
255     attr = sheet.attributes
256     attr.delete 'id'
257     attr
258   end
259   
260 end